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 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
215 SmallVectorImpl<MCInst> &Instructions);
217 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
218 SmallVectorImpl<MCInst> &Instructions);
220 bool reportParseError(Twine ErrorMsg);
221 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
223 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
224 bool parseRelocOperand(const MCExpr *&Res);
226 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
228 bool isEvaluated(const MCExpr *Expr);
229 bool parseSetMips0Directive();
230 bool parseSetArchDirective();
231 bool parseSetFeature(uint64_t Feature);
232 bool parseDirectiveCpLoad(SMLoc Loc);
233 bool parseDirectiveCPSetup();
234 bool parseDirectiveNaN();
235 bool parseDirectiveSet();
236 bool parseDirectiveOption();
237 bool parseInsnDirective();
239 bool parseSetAtDirective();
240 bool parseSetNoAtDirective();
241 bool parseSetMacroDirective();
242 bool parseSetNoMacroDirective();
243 bool parseSetMsaDirective();
244 bool parseSetNoMsaDirective();
245 bool parseSetNoDspDirective();
246 bool parseSetReorderDirective();
247 bool parseSetNoReorderDirective();
248 bool parseSetMips16Directive();
249 bool parseSetNoMips16Directive();
250 bool parseSetFpDirective();
251 bool parseSetPopDirective();
252 bool parseSetPushDirective();
253 bool parseSetSoftFloatDirective();
254 bool parseSetHardFloatDirective();
256 bool parseSetAssignment();
258 bool parseDataDirective(unsigned Size, SMLoc L);
259 bool parseDirectiveGpWord();
260 bool parseDirectiveGpDWord();
261 bool parseDirectiveModule();
262 bool parseDirectiveModuleFP();
263 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
264 StringRef Directive);
266 bool parseInternalDirectiveReallowModule();
268 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
270 bool eatComma(StringRef ErrorStr);
272 int matchCPURegisterName(StringRef Symbol);
274 int matchHWRegsRegisterName(StringRef Symbol);
276 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
278 int matchFPURegisterName(StringRef Name);
280 int matchFCCRegisterName(StringRef Name);
282 int matchACRegisterName(StringRef Name);
284 int matchMSA128RegisterName(StringRef Name);
286 int matchMSA128CtrlRegisterName(StringRef Name);
288 unsigned getReg(int RC, int RegNo);
290 unsigned getGPR(int RegNo);
292 /// Returns the internal register number for the current AT. Also checks if
293 /// the current AT is unavailable (set to $0) and gives an error if it is.
294 /// This should be used in pseudo-instruction expansions which need AT.
295 unsigned getATReg(SMLoc Loc);
297 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
298 SmallVectorImpl<MCInst> &Instructions);
300 // Helper function that checks if the value of a vector index is within the
301 // boundaries of accepted values for each RegisterKind
302 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
303 bool validateMSAIndex(int Val, int RegKind);
305 // Selects a new architecture by updating the FeatureBits with the necessary
306 // info including implied dependencies.
307 // Internally, it clears all the feature bits related to *any* architecture
308 // and selects the new one using the ToggleFeature functionality of the
309 // MCSubtargetInfo object that handles implied dependencies. The reason we
310 // clear all the arch related bits manually is because ToggleFeature only
311 // clears the features that imply the feature being cleared and not the
312 // features implied by the feature being cleared. This is easier to see
314 // --------------------------------------------------
315 // | Feature | Implies |
316 // | -------------------------------------------------|
317 // | FeatureMips1 | None |
318 // | FeatureMips2 | FeatureMips1 |
319 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
320 // | FeatureMips4 | FeatureMips3 |
322 // --------------------------------------------------
324 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
325 // FeatureMipsGP64 | FeatureMips1)
326 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
327 void selectArch(StringRef ArchFeature) {
328 FeatureBitset FeatureBits = STI.getFeatureBits();
329 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
330 STI.setFeatureBits(FeatureBits);
331 setAvailableFeatures(
332 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
333 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
336 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
337 if (!(STI.getFeatureBits()[Feature])) {
338 setAvailableFeatures(
339 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
340 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
344 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
345 if (STI.getFeatureBits()[Feature]) {
346 setAvailableFeatures(
347 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
348 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
353 enum MipsMatchResultTy {
354 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
355 #define GET_OPERAND_DIAGNOSTIC_TYPES
356 #include "MipsGenAsmMatcher.inc"
357 #undef GET_OPERAND_DIAGNOSTIC_TYPES
361 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
362 const MCInstrInfo &MII, const MCTargetOptions &Options)
363 : MCTargetAsmParser(), STI(sti),
364 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
365 sti.getCPU(), Options)) {
366 MCAsmParserExtension::Initialize(parser);
368 parser.addAliasForDirective(".asciiz", ".asciz");
370 // Initialize the set of available features.
371 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
373 // Remember the initial assembler options. The user can not modify these.
374 AssemblerOptions.push_back(
375 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
377 // Create an assembler options environment for the user to modify.
378 AssemblerOptions.push_back(
379 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
381 getTargetStreamer().updateABIInfo(*this);
383 if (!isABI_O32() && !useOddSPReg() != 0)
384 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
389 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
390 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
392 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
393 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
394 const MipsABIInfo &getABI() const { return ABI; }
395 bool isABI_N32() const { return ABI.IsN32(); }
396 bool isABI_N64() const { return ABI.IsN64(); }
397 bool isABI_O32() const { return ABI.IsO32(); }
398 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
400 bool useOddSPReg() const {
401 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
404 bool inMicroMipsMode() const {
405 return STI.getFeatureBits()[Mips::FeatureMicroMips];
407 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
408 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
409 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
410 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
411 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
412 bool hasMips32() const {
413 return STI.getFeatureBits()[Mips::FeatureMips32];
415 bool hasMips64() const {
416 return STI.getFeatureBits()[Mips::FeatureMips64];
418 bool hasMips32r2() const {
419 return STI.getFeatureBits()[Mips::FeatureMips32r2];
421 bool hasMips64r2() const {
422 return STI.getFeatureBits()[Mips::FeatureMips64r2];
424 bool hasMips32r3() const {
425 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
427 bool hasMips64r3() const {
428 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
430 bool hasMips32r5() const {
431 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
433 bool hasMips64r5() const {
434 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
436 bool hasMips32r6() const {
437 return STI.getFeatureBits()[Mips::FeatureMips32r6];
439 bool hasMips64r6() const {
440 return STI.getFeatureBits()[Mips::FeatureMips64r6];
443 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
444 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
445 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
446 bool hasCnMips() const {
447 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
450 bool inMips16Mode() const {
451 return STI.getFeatureBits()[Mips::FeatureMips16];
454 bool useSoftFloat() const {
455 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
458 /// Warn if RegIndex is the same as the current AT.
459 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
461 void warnIfNoMacro(SMLoc Loc);
467 /// MipsOperand - Instances of this class represent a parsed Mips machine
469 class MipsOperand : public MCParsedAsmOperand {
471 /// Broad categories of register classes
472 /// The exact class is finalized by the render method.
474 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
475 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
477 RegKind_FCC = 4, /// FCC
478 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
479 RegKind_MSACtrl = 16, /// MSA control registers
480 RegKind_COP2 = 32, /// COP2
481 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
483 RegKind_CCR = 128, /// CCR
484 RegKind_HWRegs = 256, /// HWRegs
485 RegKind_COP3 = 512, /// COP3
487 /// Potentially any (e.g. $1)
488 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
489 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
490 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
495 k_Immediate, /// An immediate (possibly involving symbol references)
496 k_Memory, /// Base + Offset Memory Address
497 k_PhysRegister, /// A physical register from the Mips namespace
498 k_RegisterIndex, /// A register index in one or more RegKind.
499 k_Token, /// A simple token
500 k_RegList, /// A physical register list
501 k_RegPair /// A pair of physical register
505 MipsOperand(KindTy K, MipsAsmParser &Parser)
506 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
509 /// For diagnostics, and checking the assembler temporary
510 MipsAsmParser &AsmParser;
518 unsigned Num; /// Register Number
522 unsigned Index; /// Index into the register class
523 RegKind Kind; /// Bitfield of the kinds it could possibly be
524 const MCRegisterInfo *RegInfo;
537 SmallVector<unsigned, 10> *List;
542 struct PhysRegOp PhysReg;
543 struct RegIdxOp RegIdx;
546 struct RegListOp RegList;
549 SMLoc StartLoc, EndLoc;
551 /// Internal constructor for register kinds
552 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
553 const MCRegisterInfo *RegInfo,
555 MipsAsmParser &Parser) {
556 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
557 Op->RegIdx.Index = Index;
558 Op->RegIdx.RegInfo = RegInfo;
559 Op->RegIdx.Kind = RegKind;
566 /// Coerce the register to GPR32 and return the real register for the current
568 unsigned getGPR32Reg() const {
569 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
570 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
571 unsigned ClassID = Mips::GPR32RegClassID;
572 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
575 /// Coerce the register to GPR32 and return the real register for the current
577 unsigned getGPRMM16Reg() const {
578 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
579 unsigned ClassID = Mips::GPR32RegClassID;
580 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
583 /// Coerce the register to GPR64 and return the real register for the current
585 unsigned getGPR64Reg() const {
586 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
587 unsigned ClassID = Mips::GPR64RegClassID;
588 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
592 /// Coerce the register to AFGR64 and return the real register for the current
594 unsigned getAFGR64Reg() const {
595 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
596 if (RegIdx.Index % 2 != 0)
597 AsmParser.Warning(StartLoc, "Float register should be even.");
598 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
599 .getRegister(RegIdx.Index / 2);
602 /// Coerce the register to FGR64 and return the real register for the current
604 unsigned getFGR64Reg() const {
605 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
606 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
607 .getRegister(RegIdx.Index);
610 /// Coerce the register to FGR32 and return the real register for the current
612 unsigned getFGR32Reg() const {
613 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
614 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
615 .getRegister(RegIdx.Index);
618 /// Coerce the register to FGRH32 and return the real register for the current
620 unsigned getFGRH32Reg() const {
621 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
622 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
623 .getRegister(RegIdx.Index);
626 /// Coerce the register to FCC and return the real register for the current
628 unsigned getFCCReg() const {
629 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
630 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
631 .getRegister(RegIdx.Index);
634 /// Coerce the register to MSA128 and return the real register for the current
636 unsigned getMSA128Reg() const {
637 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
638 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
640 unsigned ClassID = Mips::MSA128BRegClassID;
641 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
644 /// Coerce the register to MSACtrl and return the real register for the
646 unsigned getMSACtrlReg() const {
647 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
648 unsigned ClassID = Mips::MSACtrlRegClassID;
649 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
652 /// Coerce the register to COP2 and return the real register for the
654 unsigned getCOP2Reg() const {
655 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
656 unsigned ClassID = Mips::COP2RegClassID;
657 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
660 /// Coerce the register to COP3 and return the real register for the
662 unsigned getCOP3Reg() const {
663 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
664 unsigned ClassID = Mips::COP3RegClassID;
665 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
668 /// Coerce the register to ACC64DSP and return the real register for the
670 unsigned getACC64DSPReg() const {
671 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
672 unsigned ClassID = Mips::ACC64DSPRegClassID;
673 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
676 /// Coerce the register to HI32DSP and return the real register for the
678 unsigned getHI32DSPReg() const {
679 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
680 unsigned ClassID = Mips::HI32DSPRegClassID;
681 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
684 /// Coerce the register to LO32DSP and return the real register for the
686 unsigned getLO32DSPReg() const {
687 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
688 unsigned ClassID = Mips::LO32DSPRegClassID;
689 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
692 /// Coerce the register to CCR and return the real register for the
694 unsigned getCCRReg() const {
695 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
696 unsigned ClassID = Mips::CCRRegClassID;
697 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
700 /// Coerce the register to HWRegs and return the real register for the
702 unsigned getHWRegsReg() const {
703 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
704 unsigned ClassID = Mips::HWRegsRegClassID;
705 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
709 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
710 // Add as immediate when possible. Null MCExpr = 0.
712 Inst.addOperand(MCOperand::createImm(0));
713 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
714 Inst.addOperand(MCOperand::createImm(CE->getValue()));
716 Inst.addOperand(MCOperand::createExpr(Expr));
719 void addRegOperands(MCInst &Inst, unsigned N) const {
720 llvm_unreachable("Use a custom parser instead");
723 /// Render the operand to an MCInst as a GPR32
724 /// Asserts if the wrong number of operands are requested, or the operand
725 /// is not a k_RegisterIndex compatible with RegKind_GPR
726 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
727 assert(N == 1 && "Invalid number of operands!");
728 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
731 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
732 assert(N == 1 && "Invalid number of operands!");
733 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
736 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
737 assert(N == 1 && "Invalid number of operands!");
738 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
741 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
742 assert(N == 1 && "Invalid number of operands!");
743 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
746 /// Render the operand to an MCInst as a GPR64
747 /// Asserts if the wrong number of operands are requested, or the operand
748 /// is not a k_RegisterIndex compatible with RegKind_GPR
749 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
754 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
759 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
764 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
765 assert(N == 1 && "Invalid number of operands!");
766 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
767 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
768 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
769 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
773 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
774 assert(N == 1 && "Invalid number of operands!");
775 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
778 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::createReg(getFCCReg()));
783 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
788 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
789 assert(N == 1 && "Invalid number of operands!");
790 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
793 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
794 assert(N == 1 && "Invalid number of operands!");
795 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
798 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
799 assert(N == 1 && "Invalid number of operands!");
800 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
803 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
804 assert(N == 1 && "Invalid number of operands!");
805 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
808 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
809 assert(N == 1 && "Invalid number of operands!");
810 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
813 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 1 && "Invalid number of operands!");
815 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
818 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
819 assert(N == 1 && "Invalid number of operands!");
820 Inst.addOperand(MCOperand::createReg(getCCRReg()));
823 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
824 assert(N == 1 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
828 void addImmOperands(MCInst &Inst, unsigned N) const {
829 assert(N == 1 && "Invalid number of operands!");
830 const MCExpr *Expr = getImm();
834 void addMemOperands(MCInst &Inst, unsigned N) const {
835 assert(N == 2 && "Invalid number of operands!");
837 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
839 const MCExpr *Expr = getMemOff();
843 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
844 assert(N == 2 && "Invalid number of operands!");
846 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
848 const MCExpr *Expr = getMemOff();
852 void addRegListOperands(MCInst &Inst, unsigned N) const {
853 assert(N == 1 && "Invalid number of operands!");
855 for (auto RegNo : getRegList())
856 Inst.addOperand(MCOperand::createReg(RegNo));
859 void addRegPairOperands(MCInst &Inst, unsigned N) const {
860 assert(N == 2 && "Invalid number of operands!");
861 unsigned RegNo = getRegPair();
862 Inst.addOperand(MCOperand::createReg(RegNo++));
863 Inst.addOperand(MCOperand::createReg(RegNo));
866 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
867 assert(N == 2 && "Invalid number of operands!");
868 for (auto RegNo : getRegList())
869 Inst.addOperand(MCOperand::createReg(RegNo));
872 bool isReg() const override {
873 // As a special case until we sort out the definition of div/divu, pretend
874 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
875 if (isGPRAsmReg() && RegIdx.Index == 0)
878 return Kind == k_PhysRegister;
880 bool isRegIdx() const { return Kind == k_RegisterIndex; }
881 bool isImm() const override { return Kind == k_Immediate; }
882 bool isConstantImm() const {
883 return isImm() && dyn_cast<MCConstantExpr>(getImm());
885 template <unsigned Bits> bool isUImm() const {
886 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
888 bool isToken() const override {
889 // Note: It's not possible to pretend that other operand kinds are tokens.
890 // The matcher emitter checks tokens first.
891 return Kind == k_Token;
893 bool isMem() const override { return Kind == k_Memory; }
894 bool isConstantMemOff() const {
895 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
897 template <unsigned Bits> bool isMemWithSimmOffset() const {
898 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
900 bool isMemWithGRPMM16Base() const {
901 return isMem() && getMemBase()->isMM16AsmReg();
903 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
904 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
905 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
907 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
908 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
909 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
910 && (getMemBase()->getGPR32Reg() == Mips::SP);
912 bool isRegList16() const {
916 int Size = RegList.List->size();
917 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
918 RegList.List->back() != Mips::RA)
921 int PrevReg = *RegList.List->begin();
922 for (int i = 1; i < Size - 1; i++) {
923 int Reg = (*(RegList.List))[i];
924 if ( Reg != PrevReg + 1)
931 bool isInvNum() const { return Kind == k_Immediate; }
932 bool isLSAImm() const {
933 if (!isConstantImm())
935 int64_t Val = getConstantImm();
936 return 1 <= Val && Val <= 4;
938 bool isRegList() const { return Kind == k_RegList; }
939 bool isMovePRegPair() const {
940 if (Kind != k_RegList || RegList.List->size() != 2)
943 unsigned R0 = RegList.List->front();
944 unsigned R1 = RegList.List->back();
946 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
947 (R0 == Mips::A1 && R1 == Mips::A3) ||
948 (R0 == Mips::A2 && R1 == Mips::A3) ||
949 (R0 == Mips::A0 && R1 == Mips::S5) ||
950 (R0 == Mips::A0 && R1 == Mips::S6) ||
951 (R0 == Mips::A0 && R1 == Mips::A1) ||
952 (R0 == Mips::A0 && R1 == Mips::A2) ||
953 (R0 == Mips::A0 && R1 == Mips::A3))
959 StringRef getToken() const {
960 assert(Kind == k_Token && "Invalid access!");
961 return StringRef(Tok.Data, Tok.Length);
963 bool isRegPair() const { return Kind == k_RegPair; }
965 unsigned getReg() const override {
966 // As a special case until we sort out the definition of div/divu, pretend
967 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
968 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
969 RegIdx.Kind & RegKind_GPR)
970 return getGPR32Reg(); // FIXME: GPR64 too
972 assert(Kind == k_PhysRegister && "Invalid access!");
976 const MCExpr *getImm() const {
977 assert((Kind == k_Immediate) && "Invalid access!");
981 int64_t getConstantImm() const {
982 const MCExpr *Val = getImm();
983 return static_cast<const MCConstantExpr *>(Val)->getValue();
986 MipsOperand *getMemBase() const {
987 assert((Kind == k_Memory) && "Invalid access!");
991 const MCExpr *getMemOff() const {
992 assert((Kind == k_Memory) && "Invalid access!");
996 int64_t getConstantMemOff() const {
997 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1000 const SmallVectorImpl<unsigned> &getRegList() const {
1001 assert((Kind == k_RegList) && "Invalid access!");
1002 return *(RegList.List);
1005 unsigned getRegPair() const {
1006 assert((Kind == k_RegPair) && "Invalid access!");
1007 return RegIdx.Index;
1010 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1011 MipsAsmParser &Parser) {
1012 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1013 Op->Tok.Data = Str.data();
1014 Op->Tok.Length = Str.size();
1020 /// Create a numeric register (e.g. $1). The exact register remains
1021 /// unresolved until an instruction successfully matches
1022 static std::unique_ptr<MipsOperand>
1023 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1024 SMLoc E, MipsAsmParser &Parser) {
1025 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1026 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1029 /// Create a register that is definitely a GPR.
1030 /// This is typically only used for named registers such as $gp.
1031 static std::unique_ptr<MipsOperand>
1032 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1033 MipsAsmParser &Parser) {
1034 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1037 /// Create a register that is definitely a FGR.
1038 /// This is typically only used for named registers such as $f0.
1039 static std::unique_ptr<MipsOperand>
1040 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1041 MipsAsmParser &Parser) {
1042 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1045 /// Create a register that is definitely a HWReg.
1046 /// This is typically only used for named registers such as $hwr_cpunum.
1047 static std::unique_ptr<MipsOperand>
1048 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1049 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1050 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1053 /// Create a register that is definitely an FCC.
1054 /// This is typically only used for named registers such as $fcc0.
1055 static std::unique_ptr<MipsOperand>
1056 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1057 MipsAsmParser &Parser) {
1058 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1061 /// Create a register that is definitely an ACC.
1062 /// This is typically only used for named registers such as $ac0.
1063 static std::unique_ptr<MipsOperand>
1064 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1065 MipsAsmParser &Parser) {
1066 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1069 /// Create a register that is definitely an MSA128.
1070 /// This is typically only used for named registers such as $w0.
1071 static std::unique_ptr<MipsOperand>
1072 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1073 SMLoc E, MipsAsmParser &Parser) {
1074 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1077 /// Create a register that is definitely an MSACtrl.
1078 /// This is typically only used for named registers such as $msaaccess.
1079 static std::unique_ptr<MipsOperand>
1080 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1081 SMLoc E, MipsAsmParser &Parser) {
1082 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1085 static std::unique_ptr<MipsOperand>
1086 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1087 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1094 static std::unique_ptr<MipsOperand>
1095 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1096 SMLoc E, MipsAsmParser &Parser) {
1097 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1098 Op->Mem.Base = Base.release();
1105 static std::unique_ptr<MipsOperand>
1106 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1107 MipsAsmParser &Parser) {
1108 assert (Regs.size() > 0 && "Empty list not allowed");
1110 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1111 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1112 Op->StartLoc = StartLoc;
1113 Op->EndLoc = EndLoc;
1117 static std::unique_ptr<MipsOperand>
1118 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1119 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1120 Op->RegIdx.Index = RegNo;
1126 bool isGPRAsmReg() const {
1127 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1129 bool isMM16AsmReg() const {
1130 if (!(isRegIdx() && RegIdx.Kind))
1132 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1133 || RegIdx.Index == 16 || RegIdx.Index == 17);
1135 bool isMM16AsmRegZero() const {
1136 if (!(isRegIdx() && RegIdx.Kind))
1138 return (RegIdx.Index == 0 ||
1139 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1140 RegIdx.Index == 17);
1142 bool isMM16AsmRegMoveP() const {
1143 if (!(isRegIdx() && RegIdx.Kind))
1145 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1146 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1148 bool isFGRAsmReg() const {
1149 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1150 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1152 bool isHWRegsAsmReg() const {
1153 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1155 bool isCCRAsmReg() const {
1156 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1158 bool isFCCAsmReg() const {
1159 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1161 if (!AsmParser.hasEightFccRegisters())
1162 return RegIdx.Index == 0;
1163 return RegIdx.Index <= 7;
1165 bool isACCAsmReg() const {
1166 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1168 bool isCOP2AsmReg() const {
1169 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1171 bool isCOP3AsmReg() const {
1172 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1174 bool isMSA128AsmReg() const {
1175 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1177 bool isMSACtrlAsmReg() const {
1178 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1181 /// getStartLoc - Get the location of the first token of this operand.
1182 SMLoc getStartLoc() const override { return StartLoc; }
1183 /// getEndLoc - Get the location of the last token of this operand.
1184 SMLoc getEndLoc() const override { return EndLoc; }
1186 virtual ~MipsOperand() {
1194 delete RegList.List;
1195 case k_PhysRegister:
1196 case k_RegisterIndex:
1203 void print(raw_ostream &OS) const override {
1212 Mem.Base->print(OS);
1217 case k_PhysRegister:
1218 OS << "PhysReg<" << PhysReg.Num << ">";
1220 case k_RegisterIndex:
1221 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1228 for (auto Reg : (*RegList.List))
1233 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1237 }; // class MipsOperand
1241 extern const MCInstrDesc MipsInsts[];
1243 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1244 return MipsInsts[Opcode];
1247 static bool hasShortDelaySlot(unsigned Opcode) {
1250 case Mips::JALRS_MM:
1251 case Mips::JALRS16_MM:
1252 case Mips::BGEZALS_MM:
1253 case Mips::BLTZALS_MM:
1260 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1261 SmallVectorImpl<MCInst> &Instructions) {
1262 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1266 if (MCID.isBranch() || MCID.isCall()) {
1267 const unsigned Opcode = Inst.getOpcode();
1277 assert(hasCnMips() && "instruction only valid for octeon cpus");
1284 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1285 Offset = Inst.getOperand(2);
1286 if (!Offset.isImm())
1287 break; // We'll deal with this situation later on when applying fixups.
1288 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1289 return Error(IDLoc, "branch target out of range");
1290 if (OffsetToAlignment(Offset.getImm(),
1291 1LL << (inMicroMipsMode() ? 1 : 2)))
1292 return Error(IDLoc, "branch to misaligned address");
1306 case Mips::BGEZAL_MM:
1307 case Mips::BLTZAL_MM:
1310 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1311 Offset = Inst.getOperand(1);
1312 if (!Offset.isImm())
1313 break; // We'll deal with this situation later on when applying fixups.
1314 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1315 return Error(IDLoc, "branch target out of range");
1316 if (OffsetToAlignment(Offset.getImm(),
1317 1LL << (inMicroMipsMode() ? 1 : 2)))
1318 return Error(IDLoc, "branch to misaligned address");
1320 case Mips::BEQZ16_MM:
1321 case Mips::BNEZ16_MM:
1322 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1323 Offset = Inst.getOperand(1);
1324 if (!Offset.isImm())
1325 break; // We'll deal with this situation later on when applying fixups.
1326 if (!isIntN(8, Offset.getImm()))
1327 return Error(IDLoc, "branch target out of range");
1328 if (OffsetToAlignment(Offset.getImm(), 2LL))
1329 return Error(IDLoc, "branch to misaligned address");
1334 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1335 // We still accept it but it is a normal nop.
1336 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1337 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1338 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1343 const unsigned Opcode = Inst.getOpcode();
1355 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1356 // The offset is handled above
1357 Opnd = Inst.getOperand(1);
1359 return Error(IDLoc, "expected immediate operand kind");
1360 Imm = Opnd.getImm();
1361 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1362 Opcode == Mips::BBIT1 ? 63 : 31))
1363 return Error(IDLoc, "immediate operand value out of range");
1365 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1367 Inst.getOperand(1).setImm(Imm - 32);
1375 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1377 Opnd = Inst.getOperand(3);
1379 return Error(IDLoc, "expected immediate operand kind");
1380 Imm = Opnd.getImm();
1381 if (Imm < 0 || Imm > 31)
1382 return Error(IDLoc, "immediate operand value out of range");
1384 Opnd = Inst.getOperand(2);
1386 return Error(IDLoc, "expected immediate operand kind");
1387 Imm = Opnd.getImm();
1388 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1389 Opcode == Mips::EXTS ? 63 : 31))
1390 return Error(IDLoc, "immediate operand value out of range");
1392 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1393 Inst.getOperand(2).setImm(Imm - 32);
1399 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1400 Opnd = Inst.getOperand(2);
1402 return Error(IDLoc, "expected immediate operand kind");
1403 Imm = Opnd.getImm();
1404 if (!isInt<10>(Imm))
1405 return Error(IDLoc, "immediate operand value out of range");
1410 if (MCID.mayLoad() || MCID.mayStore()) {
1411 // Check the offset of memory operand, if it is a symbol
1412 // reference or immediate we may have to expand instructions.
1413 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1414 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1415 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1416 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1417 MCOperand &Op = Inst.getOperand(i);
1419 int MemOffset = Op.getImm();
1420 if (MemOffset < -32768 || MemOffset > 32767) {
1421 // Offset can't exceed 16bit value.
1422 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1425 } else if (Op.isExpr()) {
1426 const MCExpr *Expr = Op.getExpr();
1427 if (Expr->getKind() == MCExpr::SymbolRef) {
1428 const MCSymbolRefExpr *SR =
1429 static_cast<const MCSymbolRefExpr *>(Expr);
1430 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1432 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1435 } else if (!isEvaluated(Expr)) {
1436 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1444 if (inMicroMipsMode()) {
1445 if (MCID.mayLoad()) {
1446 // Try to create 16-bit GP relative load instruction.
1447 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1448 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1449 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1450 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1451 MCOperand &Op = Inst.getOperand(i);
1453 int MemOffset = Op.getImm();
1454 MCOperand &DstReg = Inst.getOperand(0);
1455 MCOperand &BaseReg = Inst.getOperand(1);
1456 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1457 getContext().getRegisterInfo()->getRegClass(
1458 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1459 BaseReg.getReg() == Mips::GP) {
1461 TmpInst.setLoc(IDLoc);
1462 TmpInst.setOpcode(Mips::LWGP_MM);
1463 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1464 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1465 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1466 Instructions.push_back(TmpInst);
1474 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1479 switch (Inst.getOpcode()) {
1482 case Mips::ADDIUS5_MM:
1483 Opnd = Inst.getOperand(2);
1485 return Error(IDLoc, "expected immediate operand kind");
1486 Imm = Opnd.getImm();
1487 if (Imm < -8 || Imm > 7)
1488 return Error(IDLoc, "immediate operand value out of range");
1490 case Mips::ADDIUSP_MM:
1491 Opnd = Inst.getOperand(0);
1493 return Error(IDLoc, "expected immediate operand kind");
1494 Imm = Opnd.getImm();
1495 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1497 return Error(IDLoc, "immediate operand value out of range");
1499 case Mips::SLL16_MM:
1500 case Mips::SRL16_MM:
1501 Opnd = Inst.getOperand(2);
1503 return Error(IDLoc, "expected immediate operand kind");
1504 Imm = Opnd.getImm();
1505 if (Imm < 1 || Imm > 8)
1506 return Error(IDLoc, "immediate operand value out of range");
1509 Opnd = Inst.getOperand(1);
1511 return Error(IDLoc, "expected immediate operand kind");
1512 Imm = Opnd.getImm();
1513 if (Imm < -1 || Imm > 126)
1514 return Error(IDLoc, "immediate operand value out of range");
1516 case Mips::ADDIUR2_MM:
1517 Opnd = Inst.getOperand(2);
1519 return Error(IDLoc, "expected immediate operand kind");
1520 Imm = Opnd.getImm();
1521 if (!(Imm == 1 || Imm == -1 ||
1522 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1523 return Error(IDLoc, "immediate operand value out of range");
1525 case Mips::ADDIUR1SP_MM:
1526 Opnd = Inst.getOperand(1);
1528 return Error(IDLoc, "expected immediate operand kind");
1529 Imm = Opnd.getImm();
1530 if (OffsetToAlignment(Imm, 4LL))
1531 return Error(IDLoc, "misaligned immediate operand value");
1532 if (Imm < 0 || Imm > 255)
1533 return Error(IDLoc, "immediate operand value out of range");
1535 case Mips::ANDI16_MM:
1536 Opnd = Inst.getOperand(2);
1538 return Error(IDLoc, "expected immediate operand kind");
1539 Imm = Opnd.getImm();
1540 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1541 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1542 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1543 return Error(IDLoc, "immediate operand value out of range");
1545 case Mips::LBU16_MM:
1546 Opnd = Inst.getOperand(2);
1548 return Error(IDLoc, "expected immediate operand kind");
1549 Imm = Opnd.getImm();
1550 if (Imm < -1 || Imm > 14)
1551 return Error(IDLoc, "immediate operand value out of range");
1554 Opnd = Inst.getOperand(2);
1556 return Error(IDLoc, "expected immediate operand kind");
1557 Imm = Opnd.getImm();
1558 if (Imm < 0 || Imm > 15)
1559 return Error(IDLoc, "immediate operand value out of range");
1561 case Mips::LHU16_MM:
1563 Opnd = Inst.getOperand(2);
1565 return Error(IDLoc, "expected immediate operand kind");
1566 Imm = Opnd.getImm();
1567 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1568 return Error(IDLoc, "immediate operand value out of range");
1572 Opnd = Inst.getOperand(2);
1574 return Error(IDLoc, "expected immediate operand kind");
1575 Imm = Opnd.getImm();
1576 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1577 return Error(IDLoc, "immediate operand value out of range");
1581 Opnd = Inst.getOperand(2);
1583 return Error(IDLoc, "expected immediate operand kind");
1584 Imm = Opnd.getImm();
1585 if (!isUInt<5>(Imm))
1586 return Error(IDLoc, "immediate operand value out of range");
1588 case Mips::ADDIUPC_MM:
1589 MCOperand Opnd = Inst.getOperand(1);
1591 return Error(IDLoc, "expected immediate operand kind");
1592 int Imm = Opnd.getImm();
1593 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1594 return Error(IDLoc, "immediate operand value out of range");
1599 if (needsExpansion(Inst)) {
1600 if (expandInstruction(Inst, IDLoc, Instructions))
1603 Instructions.push_back(Inst);
1605 // If this instruction has a delay slot and .set reorder is active,
1606 // emit a NOP after it.
1607 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1608 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1613 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1615 switch (Inst.getOpcode()) {
1616 case Mips::LoadImm32:
1617 case Mips::LoadImm64:
1618 case Mips::LoadAddrImm32:
1619 case Mips::LoadAddrReg32:
1620 case Mips::B_MM_Pseudo:
1623 case Mips::JalOneReg:
1624 case Mips::JalTwoReg:
1633 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1634 SmallVectorImpl<MCInst> &Instructions) {
1635 switch (Inst.getOpcode()) {
1636 default: llvm_unreachable("unimplemented expansion");
1637 case Mips::LoadImm32:
1638 return expandLoadImm(Inst, true, IDLoc, Instructions);
1639 case Mips::LoadImm64:
1640 return expandLoadImm(Inst, false, IDLoc, Instructions);
1641 case Mips::LoadAddrImm32:
1642 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1643 case Mips::LoadAddrReg32:
1644 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1645 case Mips::B_MM_Pseudo:
1646 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1649 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1650 case Mips::JalOneReg:
1651 case Mips::JalTwoReg:
1652 return expandJalWithRegs(Inst, IDLoc, Instructions);
1655 return expandBranchImm(Inst, IDLoc, Instructions);
1660 template <unsigned ShiftAmount>
1661 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1662 SmallVectorImpl<MCInst> &Instructions) {
1664 if (ShiftAmount >= 32) {
1665 tmpInst.setOpcode(Mips::DSLL32);
1666 tmpInst.addOperand(MCOperand::createReg(RegNo));
1667 tmpInst.addOperand(MCOperand::createReg(RegNo));
1668 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1669 tmpInst.setLoc(IDLoc);
1670 Instructions.push_back(tmpInst);
1672 } else if (ShiftAmount > 0) {
1673 tmpInst.setOpcode(Mips::DSLL);
1674 tmpInst.addOperand(MCOperand::createReg(RegNo));
1675 tmpInst.addOperand(MCOperand::createReg(RegNo));
1676 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1677 tmpInst.setLoc(IDLoc);
1678 Instructions.push_back(tmpInst);
1681 // There's no need for an ORi if the immediate is 0.
1682 if (Operand.isImm() && Operand.getImm() == 0)
1685 tmpInst.setOpcode(Mips::ORi);
1686 tmpInst.addOperand(MCOperand::createReg(RegNo));
1687 tmpInst.addOperand(MCOperand::createReg(RegNo));
1688 tmpInst.addOperand(Operand);
1689 tmpInst.setLoc(IDLoc);
1690 Instructions.push_back(tmpInst);
1693 template <unsigned ShiftAmount>
1694 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1695 SmallVectorImpl<MCInst> &Instructions) {
1696 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1701 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1702 SmallVectorImpl<MCInst> &Instructions) {
1703 // Create a JALR instruction which is going to replace the pseudo-JAL.
1705 JalrInst.setLoc(IDLoc);
1706 const MCOperand FirstRegOp = Inst.getOperand(0);
1707 const unsigned Opcode = Inst.getOpcode();
1709 if (Opcode == Mips::JalOneReg) {
1710 // jal $rs => jalr $rs
1711 if (inMicroMipsMode()) {
1712 JalrInst.setOpcode(Mips::JALR16_MM);
1713 JalrInst.addOperand(FirstRegOp);
1715 JalrInst.setOpcode(Mips::JALR);
1716 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1717 JalrInst.addOperand(FirstRegOp);
1719 } else if (Opcode == Mips::JalTwoReg) {
1720 // jal $rd, $rs => jalr $rd, $rs
1721 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1722 JalrInst.addOperand(FirstRegOp);
1723 const MCOperand SecondRegOp = Inst.getOperand(1);
1724 JalrInst.addOperand(SecondRegOp);
1726 Instructions.push_back(JalrInst);
1728 // If .set reorder is active, emit a NOP after it.
1729 if (AssemblerOptions.back()->isReorder()) {
1730 // This is a 32-bit NOP because these 2 pseudo-instructions
1731 // do not have a short delay slot.
1733 NopInst.setOpcode(Mips::SLL);
1734 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1735 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1736 NopInst.addOperand(MCOperand::createImm(0));
1737 Instructions.push_back(NopInst);
1743 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1744 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1745 SmallVectorImpl<MCInst> &Instructions) {
1746 if (!Is32BitImm && !isGP64bit()) {
1747 Error(IDLoc, "instruction requires a 64-bit architecture");
1751 bool UseSrcReg = false;
1752 if (SrcReg != Mips::NoRegister)
1757 tmpInst.setLoc(IDLoc);
1758 // FIXME: gas has a special case for values that are 000...1111, which
1759 // becomes a li -1 and then a dsrl
1760 if (0 <= ImmValue && ImmValue <= 65535) {
1761 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1762 // li d,j => ori d,$zero,j
1764 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1765 tmpInst.setOpcode(Mips::ORi);
1766 tmpInst.addOperand(MCOperand::createReg(DstReg));
1767 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1768 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1769 Instructions.push_back(tmpInst);
1770 } else if (ImmValue < 0 && ImmValue >= -32768) {
1771 // For negative signed 16-bit values (-32768 <= j < 0):
1772 // li d,j => addiu d,$zero,j
1774 SrcReg = Mips::ZERO;
1775 tmpInst.setOpcode(Mips::ADDiu);
1776 tmpInst.addOperand(MCOperand::createReg(DstReg));
1777 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1778 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1779 Instructions.push_back(tmpInst);
1780 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1781 warnIfNoMacro(IDLoc);
1783 // For all other values which are representable as a 32-bit integer:
1784 // li d,j => lui d,hi16(j)
1786 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1787 uint16_t Bits15To0 = ImmValue & 0xffff;
1789 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1790 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1792 tmpInst.setOpcode(Mips::ORi);
1793 tmpInst.addOperand(MCOperand::createReg(DstReg));
1794 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1795 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1796 tmpInst.setLoc(IDLoc);
1797 Instructions.push_back(tmpInst);
1798 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1799 createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
1801 tmpInst.setOpcode(Mips::LUi);
1802 tmpInst.addOperand(MCOperand::createReg(DstReg));
1803 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1804 Instructions.push_back(tmpInst);
1806 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1809 createAddu(DstReg, DstReg, SrcReg, Instructions);
1811 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1813 Error(IDLoc, "instruction requires a 32-bit immediate");
1816 warnIfNoMacro(IDLoc);
1818 // <------- lo32 ------>
1819 // <------- hi32 ------>
1820 // <- hi16 -> <- lo16 ->
1821 // _________________________________
1823 // | 16-bits | 16-bits | 16-bits |
1824 // |__________|__________|__________|
1826 // For any 64-bit value that is representable as a 48-bit integer:
1827 // li d,j => lui d,hi16(j)
1828 // ori d,d,hi16(lo32(j))
1830 // ori d,d,lo16(lo32(j))
1831 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1832 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1833 uint16_t Bits15To0 = ImmValue & 0xffff;
1835 tmpInst.setOpcode(Mips::LUi);
1836 tmpInst.addOperand(MCOperand::createReg(DstReg));
1837 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1838 Instructions.push_back(tmpInst);
1839 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1840 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1843 createAddu(DstReg, DstReg, SrcReg, Instructions);
1847 Error(IDLoc, "instruction requires a 32-bit immediate");
1850 warnIfNoMacro(IDLoc);
1852 // <------- hi32 ------> <------- lo32 ------>
1853 // <- hi16 -> <- lo16 ->
1854 // ___________________________________________
1856 // | 16-bits | 16-bits | 16-bits | 16-bits |
1857 // |__________|__________|__________|__________|
1859 // For all other values which are representable as a 64-bit integer:
1860 // li d,j => lui d,hi16(j)
1861 // ori d,d,lo16(hi32(j))
1863 // ori d,d,hi16(lo32(j))
1865 // ori d,d,lo16(lo32(j))
1866 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1867 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1868 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1869 uint16_t Bits15To0 = ImmValue & 0xffff;
1871 tmpInst.setOpcode(Mips::LUi);
1872 tmpInst.addOperand(MCOperand::createReg(DstReg));
1873 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1874 Instructions.push_back(tmpInst);
1875 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1877 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1878 // two left shifts of 16 bits.
1879 if (Bits31To16 == 0) {
1880 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1882 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1883 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1887 createAddu(DstReg, DstReg, SrcReg, Instructions);
1892 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1893 SmallVectorImpl<MCInst> &Instructions) {
1894 const MCOperand &ImmOp = Inst.getOperand(1);
1895 assert(ImmOp.isImm() && "expected immediate operand kind");
1896 const MCOperand &DstRegOp = Inst.getOperand(0);
1897 assert(DstRegOp.isReg() && "expected register operand kind");
1899 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1900 Is32BitImm, IDLoc, Instructions))
1907 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1908 SmallVectorImpl<MCInst> &Instructions) {
1909 const MCOperand &DstRegOp = Inst.getOperand(0);
1910 assert(DstRegOp.isReg() && "expected register operand kind");
1912 const MCOperand &ImmOp = Inst.getOperand(2);
1913 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1914 "expected immediate operand kind");
1915 if (!ImmOp.isImm()) {
1916 if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Is32BitImm, IDLoc,
1922 const MCOperand &SrcRegOp = Inst.getOperand(1);
1923 assert(SrcRegOp.isReg() && "expected register operand kind");
1925 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1926 Is32BitImm, IDLoc, Instructions))
1933 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1934 SmallVectorImpl<MCInst> &Instructions) {
1935 const MCOperand &DstRegOp = Inst.getOperand(0);
1936 assert(DstRegOp.isReg() && "expected register operand kind");
1938 const MCOperand &ImmOp = Inst.getOperand(1);
1939 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1940 "expected immediate operand kind");
1941 if (!ImmOp.isImm()) {
1942 if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Is32BitImm, IDLoc,
1949 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1950 Is32BitImm, IDLoc, Instructions))
1956 bool MipsAsmParser::loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
1957 bool Is32BitSym, SMLoc IDLoc,
1958 SmallVectorImpl<MCInst> &Instructions) {
1959 warnIfNoMacro(IDLoc);
1961 if (Is32BitSym && isABI_N64())
1962 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1965 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
1966 const MCSymbolRefExpr *HiExpr =
1967 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1968 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1969 const MCSymbolRefExpr *LoExpr =
1970 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1971 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1973 // If it's a 64-bit architecture, expand to:
1974 // la d,sym => lui d,highest(sym)
1975 // ori d,d,higher(sym)
1977 // ori d,d,hi16(sym)
1979 // ori d,d,lo16(sym)
1980 const MCSymbolRefExpr *HighestExpr =
1981 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1982 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1983 const MCSymbolRefExpr *HigherExpr =
1984 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1985 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1987 tmpInst.setOpcode(Mips::LUi);
1988 tmpInst.addOperand(MCOperand::createReg(DstReg));
1989 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1990 Instructions.push_back(tmpInst);
1992 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), DstReg, SMLoc(),
1994 createLShiftOri<16>(MCOperand::createExpr(HiExpr), DstReg, SMLoc(),
1996 createLShiftOri<16>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(),
1999 // Otherwise, expand to:
2000 // la d,sym => lui d,hi16(sym)
2001 // ori d,d,lo16(sym)
2002 tmpInst.setOpcode(Mips::LUi);
2003 tmpInst.addOperand(MCOperand::createReg(DstReg));
2004 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2005 Instructions.push_back(tmpInst);
2007 createLShiftOri<0>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(),
2013 bool MipsAsmParser::expandUncondBranchMMPseudo(
2014 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2015 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2016 "unexpected number of operands");
2018 MCOperand Offset = Inst.getOperand(0);
2019 if (Offset.isExpr()) {
2021 Inst.setOpcode(Mips::BEQ_MM);
2022 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2023 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2024 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2026 assert(Offset.isImm() && "expected immediate operand kind");
2027 if (isIntN(11, Offset.getImm())) {
2028 // If offset fits into 11 bits then this instruction becomes microMIPS
2029 // 16-bit unconditional branch instruction.
2030 Inst.setOpcode(Mips::B16_MM);
2032 if (!isIntN(17, Offset.getImm()))
2033 Error(IDLoc, "branch target out of range");
2034 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2035 Error(IDLoc, "branch to misaligned address");
2037 Inst.setOpcode(Mips::BEQ_MM);
2038 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2039 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2040 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2043 Instructions.push_back(Inst);
2045 // If .set reorder is active, emit a NOP after the branch instruction.
2046 if (AssemblerOptions.back()->isReorder())
2047 createNop(true, IDLoc, Instructions);
2052 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2053 SmallVectorImpl<MCInst> &Instructions) {
2054 const MCOperand &DstRegOp = Inst.getOperand(0);
2055 assert(DstRegOp.isReg() && "expected register operand kind");
2057 const MCOperand &ImmOp = Inst.getOperand(1);
2058 assert(ImmOp.isImm() && "expected immediate operand kind");
2060 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2061 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2063 unsigned OpCode = 0;
2064 switch(Inst.getOpcode()) {
2072 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2076 int64_t ImmValue = ImmOp.getImm();
2077 if (ImmValue == 0) {
2079 BranchInst.setOpcode(OpCode);
2080 BranchInst.addOperand(DstRegOp);
2081 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2082 BranchInst.addOperand(MemOffsetOp);
2083 Instructions.push_back(BranchInst);
2085 warnIfNoMacro(IDLoc);
2087 unsigned ATReg = getATReg(IDLoc);
2091 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2096 BranchInst.setOpcode(OpCode);
2097 BranchInst.addOperand(DstRegOp);
2098 BranchInst.addOperand(MCOperand::createReg(ATReg));
2099 BranchInst.addOperand(MemOffsetOp);
2100 Instructions.push_back(BranchInst);
2105 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2106 SmallVectorImpl<MCInst> &Instructions,
2107 bool isLoad, bool isImmOpnd) {
2108 const MCSymbolRefExpr *SR;
2110 unsigned ImmOffset, HiOffset, LoOffset;
2111 const MCExpr *ExprOffset;
2113 // 1st operand is either the source or destination register.
2114 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2115 unsigned RegOpNum = Inst.getOperand(0).getReg();
2116 // 2nd operand is the base register.
2117 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2118 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2119 // 3rd operand is either an immediate or expression.
2121 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2122 ImmOffset = Inst.getOperand(2).getImm();
2123 LoOffset = ImmOffset & 0x0000ffff;
2124 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2125 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2126 if (LoOffset & 0x8000)
2129 ExprOffset = Inst.getOperand(2).getExpr();
2130 // All instructions will have the same location.
2131 TempInst.setLoc(IDLoc);
2132 // These are some of the types of expansions we perform here:
2133 // 1) lw $8, sym => lui $8, %hi(sym)
2134 // lw $8, %lo(sym)($8)
2135 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2137 // lw $8, %lo(offset)($9)
2138 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2140 // lw $8, %lo(offset)($at)
2141 // 4) sw $8, sym => lui $at, %hi(sym)
2142 // sw $8, %lo(sym)($at)
2143 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2145 // sw $8, %lo(offset)($at)
2146 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2147 // ldc1 $f0, %lo(sym)($at)
2149 // For load instructions we can use the destination register as a temporary
2150 // if base and dst are different (examples 1 and 2) and if the base register
2151 // is general purpose otherwise we must use $at (example 6) and error if it's
2152 // not available. For stores we must use $at (examples 4 and 5) because we
2153 // must not clobber the source register setting up the offset.
2154 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2155 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2156 unsigned RegClassIDOp0 =
2157 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2158 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2159 (RegClassIDOp0 == Mips::GPR64RegClassID);
2160 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2161 TmpRegNum = RegOpNum;
2163 // At this point we need AT to perform the expansions and we exit if it is
2165 TmpRegNum = getATReg(IDLoc);
2170 TempInst.setOpcode(Mips::LUi);
2171 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2173 TempInst.addOperand(MCOperand::createImm(HiOffset));
2175 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2176 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2177 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2178 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2180 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2182 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2183 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2186 // Add the instruction to the list.
2187 Instructions.push_back(TempInst);
2188 // Prepare TempInst for next instruction.
2190 // Add temp register to base.
2191 if (BaseRegNum != Mips::ZERO) {
2192 TempInst.setOpcode(Mips::ADDu);
2193 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2194 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2195 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2196 Instructions.push_back(TempInst);
2199 // And finally, create original instruction with low part
2200 // of offset and new base.
2201 TempInst.setOpcode(Inst.getOpcode());
2202 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2203 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2205 TempInst.addOperand(MCOperand::createImm(LoOffset));
2207 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2208 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2209 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2211 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2213 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2214 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2217 Instructions.push_back(TempInst);
2222 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2223 SmallVectorImpl<MCInst> &Instructions) {
2224 unsigned OpNum = Inst.getNumOperands();
2225 unsigned Opcode = Inst.getOpcode();
2226 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2228 assert (Inst.getOperand(OpNum - 1).isImm() &&
2229 Inst.getOperand(OpNum - 2).isReg() &&
2230 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2232 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2233 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2234 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2235 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2236 // It can be implemented as SWM16 or LWM16 instruction.
2237 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2239 Inst.setOpcode(NewOpcode);
2240 Instructions.push_back(Inst);
2244 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2245 SmallVectorImpl<MCInst> &Instructions) {
2247 if (hasShortDelaySlot) {
2248 NopInst.setOpcode(Mips::MOVE16_MM);
2249 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2250 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2252 NopInst.setOpcode(Mips::SLL);
2253 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2254 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2255 NopInst.addOperand(MCOperand::createImm(0));
2257 Instructions.push_back(NopInst);
2260 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2262 SmallVectorImpl<MCInst> &Instructions) {
2264 AdduInst.setOpcode(Mips::ADDu);
2265 AdduInst.addOperand(MCOperand::createReg(DstReg));
2266 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2267 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2268 Instructions.push_back(AdduInst);
2271 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2272 // As described by the Mips32r2 spec, the registers Rd and Rs for
2273 // jalr.hb must be different.
2274 unsigned Opcode = Inst.getOpcode();
2276 if (Opcode == Mips::JALR_HB &&
2277 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2278 return Match_RequiresDifferentSrcAndDst;
2280 return Match_Success;
2283 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2284 OperandVector &Operands,
2286 uint64_t &ErrorInfo,
2287 bool MatchingInlineAsm) {
2290 SmallVector<MCInst, 8> Instructions;
2291 unsigned MatchResult =
2292 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2294 switch (MatchResult) {
2295 case Match_Success: {
2296 if (processInstruction(Inst, IDLoc, Instructions))
2298 for (unsigned i = 0; i < Instructions.size(); i++)
2299 Out.EmitInstruction(Instructions[i], STI);
2302 case Match_MissingFeature:
2303 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2305 case Match_InvalidOperand: {
2306 SMLoc ErrorLoc = IDLoc;
2307 if (ErrorInfo != ~0ULL) {
2308 if (ErrorInfo >= Operands.size())
2309 return Error(IDLoc, "too few operands for instruction");
2311 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2312 if (ErrorLoc == SMLoc())
2316 return Error(ErrorLoc, "invalid operand for instruction");
2318 case Match_MnemonicFail:
2319 return Error(IDLoc, "invalid instruction");
2320 case Match_RequiresDifferentSrcAndDst:
2321 return Error(IDLoc, "source and destination must be different");
2324 llvm_unreachable("Implement any new match types added!");
2327 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2328 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2329 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2330 ") without \".set noat\"");
2333 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2334 if (!AssemblerOptions.back()->isMacro())
2335 Warning(Loc, "macro instruction expanded into multiple instructions");
2339 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2340 SMRange Range, bool ShowColors) {
2341 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2342 Range, SMFixIt(Range, FixMsg),
2346 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2349 CC = StringSwitch<unsigned>(Name)
2385 if (!(isABI_N32() || isABI_N64()))
2388 if (12 <= CC && CC <= 15) {
2389 // Name is one of t4-t7
2390 AsmToken RegTok = getLexer().peekTok();
2391 SMRange RegRange = RegTok.getLocRange();
2393 StringRef FixedName = StringSwitch<StringRef>(Name)
2399 assert(FixedName != "" && "Register name is not one of t4-t7.");
2401 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2402 "Did you mean $" + FixedName + "?", RegRange);
2405 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2406 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2407 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2408 if (8 <= CC && CC <= 11)
2412 CC = StringSwitch<unsigned>(Name)
2424 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2427 CC = StringSwitch<unsigned>(Name)
2428 .Case("hwr_cpunum", 0)
2429 .Case("hwr_synci_step", 1)
2431 .Case("hwr_ccres", 3)
2432 .Case("hwr_ulr", 29)
2438 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2440 if (Name[0] == 'f') {
2441 StringRef NumString = Name.substr(1);
2443 if (NumString.getAsInteger(10, IntVal))
2444 return -1; // This is not an integer.
2445 if (IntVal > 31) // Maximum index for fpu register.
2452 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2454 if (Name.startswith("fcc")) {
2455 StringRef NumString = Name.substr(3);
2457 if (NumString.getAsInteger(10, IntVal))
2458 return -1; // This is not an integer.
2459 if (IntVal > 7) // There are only 8 fcc registers.
2466 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2468 if (Name.startswith("ac")) {
2469 StringRef NumString = Name.substr(2);
2471 if (NumString.getAsInteger(10, IntVal))
2472 return -1; // This is not an integer.
2473 if (IntVal > 3) // There are only 3 acc registers.
2480 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2483 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2492 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2495 CC = StringSwitch<unsigned>(Name)
2498 .Case("msaaccess", 2)
2500 .Case("msamodify", 4)
2501 .Case("msarequest", 5)
2503 .Case("msaunmap", 7)
2509 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2510 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2512 reportParseError(Loc,
2513 "pseudo-instruction requires $at, which is not available");
2516 unsigned AT = getReg(
2517 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2521 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2522 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2525 unsigned MipsAsmParser::getGPR(int RegNo) {
2526 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2530 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2532 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2535 return getReg(RegClass, RegNum);
2538 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2539 MCAsmParser &Parser = getParser();
2540 DEBUG(dbgs() << "parseOperand\n");
2542 // Check if the current operand has a custom associated parser, if so, try to
2543 // custom parse the operand, or fallback to the general approach.
2544 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2545 if (ResTy == MatchOperand_Success)
2547 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2548 // there was a match, but an error occurred, in which case, just return that
2549 // the operand parsing failed.
2550 if (ResTy == MatchOperand_ParseFail)
2553 DEBUG(dbgs() << ".. Generic Parser\n");
2555 switch (getLexer().getKind()) {
2557 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2559 case AsmToken::Dollar: {
2560 // Parse the register.
2561 SMLoc S = Parser.getTok().getLoc();
2563 // Almost all registers have been parsed by custom parsers. There is only
2564 // one exception to this. $zero (and it's alias $0) will reach this point
2565 // for div, divu, and similar instructions because it is not an operand
2566 // to the instruction definition but an explicit register. Special case
2567 // this situation for now.
2568 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2571 // Maybe it is a symbol reference.
2572 StringRef Identifier;
2573 if (Parser.parseIdentifier(Identifier))
2576 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2577 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2578 // Otherwise create a symbol reference.
2580 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2582 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2585 // Else drop to expression parsing.
2586 case AsmToken::LParen:
2587 case AsmToken::Minus:
2588 case AsmToken::Plus:
2589 case AsmToken::Integer:
2590 case AsmToken::Tilde:
2591 case AsmToken::String: {
2592 DEBUG(dbgs() << ".. generic integer\n");
2593 OperandMatchResultTy ResTy = parseImm(Operands);
2594 return ResTy != MatchOperand_Success;
2596 case AsmToken::Percent: {
2597 // It is a symbol reference or constant expression.
2598 const MCExpr *IdVal;
2599 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2600 if (parseRelocOperand(IdVal))
2603 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2605 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2607 } // case AsmToken::Percent
2608 } // switch(getLexer().getKind())
2612 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2613 StringRef RelocStr) {
2615 // Check the type of the expression.
2616 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2617 // It's a constant, evaluate reloc value.
2619 switch (getVariantKind(RelocStr)) {
2620 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2621 // Get the 1st 16-bits.
2622 Val = MCE->getValue() & 0xffff;
2624 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2625 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2626 // 16 bits being negative.
2627 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2629 case MCSymbolRefExpr::VK_Mips_HIGHER:
2630 // Get the 3rd 16-bits.
2631 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2633 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2634 // Get the 4th 16-bits.
2635 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2638 report_fatal_error("unsupported reloc value");
2640 return MCConstantExpr::create(Val, getContext());
2643 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2644 // It's a symbol, create a symbolic expression from the symbol.
2645 StringRef Symbol = MSRE->getSymbol().getName();
2646 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2647 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
2651 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2652 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2654 // Try to create target expression.
2655 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2656 return MipsMCExpr::create(VK, Expr, getContext());
2658 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2659 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2660 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
2664 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2665 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2666 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
2669 // Just return the original expression.
2673 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2675 switch (Expr->getKind()) {
2676 case MCExpr::Constant:
2678 case MCExpr::SymbolRef:
2679 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2680 case MCExpr::Binary:
2681 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2682 if (!isEvaluated(BE->getLHS()))
2684 return isEvaluated(BE->getRHS());
2687 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2688 case MCExpr::Target:
2694 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2695 MCAsmParser &Parser = getParser();
2696 Parser.Lex(); // Eat the % token.
2697 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2698 if (Tok.isNot(AsmToken::Identifier))
2701 std::string Str = Tok.getIdentifier();
2703 Parser.Lex(); // Eat the identifier.
2704 // Now make an expression from the rest of the operand.
2705 const MCExpr *IdVal;
2708 if (getLexer().getKind() == AsmToken::LParen) {
2710 Parser.Lex(); // Eat the '(' token.
2711 if (getLexer().getKind() == AsmToken::Percent) {
2712 Parser.Lex(); // Eat the % token.
2713 const AsmToken &nextTok = Parser.getTok();
2714 if (nextTok.isNot(AsmToken::Identifier))
2717 Str += nextTok.getIdentifier();
2718 Parser.Lex(); // Eat the identifier.
2719 if (getLexer().getKind() != AsmToken::LParen)
2724 if (getParser().parseParenExpression(IdVal, EndLoc))
2727 while (getLexer().getKind() == AsmToken::RParen)
2728 Parser.Lex(); // Eat the ')' token.
2731 return true; // Parenthesis must follow the relocation operand.
2733 Res = evaluateRelocExpr(IdVal, Str);
2737 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2739 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2740 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2741 if (ResTy == MatchOperand_Success) {
2742 assert(Operands.size() == 1);
2743 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2744 StartLoc = Operand.getStartLoc();
2745 EndLoc = Operand.getEndLoc();
2747 // AFAIK, we only support numeric registers and named GPR's in CFI
2749 // Don't worry about eating tokens before failing. Using an unrecognised
2750 // register is a parse error.
2751 if (Operand.isGPRAsmReg()) {
2752 // Resolve to GPR32 or GPR64 appropriately.
2753 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2756 return (RegNo == (unsigned)-1);
2759 assert(Operands.size() == 0);
2760 return (RegNo == (unsigned)-1);
2763 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2764 MCAsmParser &Parser = getParser();
2768 while (getLexer().getKind() == AsmToken::LParen)
2771 switch (getLexer().getKind()) {
2774 case AsmToken::Identifier:
2775 case AsmToken::LParen:
2776 case AsmToken::Integer:
2777 case AsmToken::Minus:
2778 case AsmToken::Plus:
2780 Result = getParser().parseParenExpression(Res, S);
2782 Result = (getParser().parseExpression(Res));
2783 while (getLexer().getKind() == AsmToken::RParen)
2786 case AsmToken::Percent:
2787 Result = parseRelocOperand(Res);
2792 MipsAsmParser::OperandMatchResultTy
2793 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2794 MCAsmParser &Parser = getParser();
2795 DEBUG(dbgs() << "parseMemOperand\n");
2796 const MCExpr *IdVal = nullptr;
2798 bool isParenExpr = false;
2799 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2800 // First operand is the offset.
2801 S = Parser.getTok().getLoc();
2803 if (getLexer().getKind() == AsmToken::LParen) {
2808 if (getLexer().getKind() != AsmToken::Dollar) {
2809 if (parseMemOffset(IdVal, isParenExpr))
2810 return MatchOperand_ParseFail;
2812 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2813 if (Tok.isNot(AsmToken::LParen)) {
2814 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2815 if (Mnemonic.getToken() == "la") {
2817 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2818 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2819 return MatchOperand_Success;
2821 if (Tok.is(AsmToken::EndOfStatement)) {
2823 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2825 // Zero register assumed, add a memory operand with ZERO as its base.
2826 // "Base" will be managed by k_Memory.
2827 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2830 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2831 return MatchOperand_Success;
2833 Error(Parser.getTok().getLoc(), "'(' expected");
2834 return MatchOperand_ParseFail;
2837 Parser.Lex(); // Eat the '(' token.
2840 Res = parseAnyRegister(Operands);
2841 if (Res != MatchOperand_Success)
2844 if (Parser.getTok().isNot(AsmToken::RParen)) {
2845 Error(Parser.getTok().getLoc(), "')' expected");
2846 return MatchOperand_ParseFail;
2849 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2851 Parser.Lex(); // Eat the ')' token.
2854 IdVal = MCConstantExpr::create(0, getContext());
2856 // Replace the register operand with the memory operand.
2857 std::unique_ptr<MipsOperand> op(
2858 static_cast<MipsOperand *>(Operands.back().release()));
2859 // Remove the register from the operands.
2860 // "op" will be managed by k_Memory.
2861 Operands.pop_back();
2862 // Add the memory operand.
2863 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2865 if (IdVal->evaluateAsAbsolute(Imm))
2866 IdVal = MCConstantExpr::create(Imm, getContext());
2867 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2868 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2872 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2873 return MatchOperand_Success;
2876 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2877 MCAsmParser &Parser = getParser();
2878 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
2880 SMLoc S = Parser.getTok().getLoc();
2882 if (Sym->isVariable())
2883 Expr = Sym->getVariableValue();
2886 if (Expr->getKind() == MCExpr::SymbolRef) {
2887 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2888 StringRef DefSymbol = Ref->getSymbol().getName();
2889 if (DefSymbol.startswith("$")) {
2890 OperandMatchResultTy ResTy =
2891 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2892 if (ResTy == MatchOperand_Success) {
2895 } else if (ResTy == MatchOperand_ParseFail)
2896 llvm_unreachable("Should never ParseFail");
2899 } else if (Expr->getKind() == MCExpr::Constant) {
2901 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2903 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2910 MipsAsmParser::OperandMatchResultTy
2911 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2912 StringRef Identifier,
2914 int Index = matchCPURegisterName(Identifier);
2916 Operands.push_back(MipsOperand::createGPRReg(
2917 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2918 return MatchOperand_Success;
2921 Index = matchHWRegsRegisterName(Identifier);
2923 Operands.push_back(MipsOperand::createHWRegsReg(
2924 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2925 return MatchOperand_Success;
2928 Index = matchFPURegisterName(Identifier);
2930 Operands.push_back(MipsOperand::createFGRReg(
2931 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2932 return MatchOperand_Success;
2935 Index = matchFCCRegisterName(Identifier);
2937 Operands.push_back(MipsOperand::createFCCReg(
2938 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2939 return MatchOperand_Success;
2942 Index = matchACRegisterName(Identifier);
2944 Operands.push_back(MipsOperand::createACCReg(
2945 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2946 return MatchOperand_Success;
2949 Index = matchMSA128RegisterName(Identifier);
2951 Operands.push_back(MipsOperand::createMSA128Reg(
2952 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2953 return MatchOperand_Success;
2956 Index = matchMSA128CtrlRegisterName(Identifier);
2958 Operands.push_back(MipsOperand::createMSACtrlReg(
2959 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2960 return MatchOperand_Success;
2963 return MatchOperand_NoMatch;
2966 MipsAsmParser::OperandMatchResultTy
2967 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2968 MCAsmParser &Parser = getParser();
2969 auto Token = Parser.getLexer().peekTok(false);
2971 if (Token.is(AsmToken::Identifier)) {
2972 DEBUG(dbgs() << ".. identifier\n");
2973 StringRef Identifier = Token.getIdentifier();
2974 OperandMatchResultTy ResTy =
2975 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2977 } else if (Token.is(AsmToken::Integer)) {
2978 DEBUG(dbgs() << ".. integer\n");
2979 Operands.push_back(MipsOperand::createNumericReg(
2980 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2982 return MatchOperand_Success;
2985 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2987 return MatchOperand_NoMatch;
2990 MipsAsmParser::OperandMatchResultTy
2991 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2992 MCAsmParser &Parser = getParser();
2993 DEBUG(dbgs() << "parseAnyRegister\n");
2995 auto Token = Parser.getTok();
2997 SMLoc S = Token.getLoc();
2999 if (Token.isNot(AsmToken::Dollar)) {
3000 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3001 if (Token.is(AsmToken::Identifier)) {
3002 if (searchSymbolAlias(Operands))
3003 return MatchOperand_Success;
3005 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3006 return MatchOperand_NoMatch;
3008 DEBUG(dbgs() << ".. $\n");
3010 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3011 if (ResTy == MatchOperand_Success) {
3013 Parser.Lex(); // identifier
3018 MipsAsmParser::OperandMatchResultTy
3019 MipsAsmParser::parseImm(OperandVector &Operands) {
3020 MCAsmParser &Parser = getParser();
3021 switch (getLexer().getKind()) {
3023 return MatchOperand_NoMatch;
3024 case AsmToken::LParen:
3025 case AsmToken::Minus:
3026 case AsmToken::Plus:
3027 case AsmToken::Integer:
3028 case AsmToken::Tilde:
3029 case AsmToken::String:
3033 const MCExpr *IdVal;
3034 SMLoc S = Parser.getTok().getLoc();
3035 if (getParser().parseExpression(IdVal))
3036 return MatchOperand_ParseFail;
3038 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3039 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3040 return MatchOperand_Success;
3043 MipsAsmParser::OperandMatchResultTy
3044 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3045 MCAsmParser &Parser = getParser();
3046 DEBUG(dbgs() << "parseJumpTarget\n");
3048 SMLoc S = getLexer().getLoc();
3050 // Integers and expressions are acceptable
3051 OperandMatchResultTy ResTy = parseImm(Operands);
3052 if (ResTy != MatchOperand_NoMatch)
3055 // Registers are a valid target and have priority over symbols.
3056 ResTy = parseAnyRegister(Operands);
3057 if (ResTy != MatchOperand_NoMatch)
3060 const MCExpr *Expr = nullptr;
3061 if (Parser.parseExpression(Expr)) {
3062 // We have no way of knowing if a symbol was consumed so we must ParseFail
3063 return MatchOperand_ParseFail;
3066 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3067 return MatchOperand_Success;
3070 MipsAsmParser::OperandMatchResultTy
3071 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3072 MCAsmParser &Parser = getParser();
3073 const MCExpr *IdVal;
3074 // If the first token is '$' we may have register operand.
3075 if (Parser.getTok().is(AsmToken::Dollar))
3076 return MatchOperand_NoMatch;
3077 SMLoc S = Parser.getTok().getLoc();
3078 if (getParser().parseExpression(IdVal))
3079 return MatchOperand_ParseFail;
3080 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3081 assert(MCE && "Unexpected MCExpr type.");
3082 int64_t Val = MCE->getValue();
3083 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3084 Operands.push_back(MipsOperand::CreateImm(
3085 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3086 return MatchOperand_Success;
3089 MipsAsmParser::OperandMatchResultTy
3090 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3091 MCAsmParser &Parser = getParser();
3092 switch (getLexer().getKind()) {
3094 return MatchOperand_NoMatch;
3095 case AsmToken::LParen:
3096 case AsmToken::Plus:
3097 case AsmToken::Minus:
3098 case AsmToken::Integer:
3103 SMLoc S = Parser.getTok().getLoc();
3105 if (getParser().parseExpression(Expr))
3106 return MatchOperand_ParseFail;
3109 if (!Expr->evaluateAsAbsolute(Val)) {
3110 Error(S, "expected immediate value");
3111 return MatchOperand_ParseFail;
3114 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3115 // and because the CPU always adds one to the immediate field, the allowed
3116 // range becomes 1..4. We'll only check the range here and will deal
3117 // with the addition/subtraction when actually decoding/encoding
3119 if (Val < 1 || Val > 4) {
3120 Error(S, "immediate not in range (1..4)");
3121 return MatchOperand_ParseFail;
3125 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3126 return MatchOperand_Success;
3129 MipsAsmParser::OperandMatchResultTy
3130 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3131 MCAsmParser &Parser = getParser();
3132 SmallVector<unsigned, 10> Regs;
3134 unsigned PrevReg = Mips::NoRegister;
3135 bool RegRange = false;
3136 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3138 if (Parser.getTok().isNot(AsmToken::Dollar))
3139 return MatchOperand_ParseFail;
3141 SMLoc S = Parser.getTok().getLoc();
3142 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3143 SMLoc E = getLexer().getLoc();
3144 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3145 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3147 // Remove last register operand because registers from register range
3148 // should be inserted first.
3149 if (RegNo == Mips::RA) {
3150 Regs.push_back(RegNo);
3152 unsigned TmpReg = PrevReg + 1;
3153 while (TmpReg <= RegNo) {
3154 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3155 Error(E, "invalid register operand");
3156 return MatchOperand_ParseFail;
3160 Regs.push_back(TmpReg++);
3166 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3167 (RegNo != Mips::RA)) {
3168 Error(E, "$16 or $31 expected");
3169 return MatchOperand_ParseFail;
3170 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3171 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3172 Error(E, "invalid register operand");
3173 return MatchOperand_ParseFail;
3174 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3175 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3176 Error(E, "consecutive register numbers expected");
3177 return MatchOperand_ParseFail;
3180 Regs.push_back(RegNo);
3183 if (Parser.getTok().is(AsmToken::Minus))
3186 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3187 !Parser.getTok().isNot(AsmToken::Comma)) {
3188 Error(E, "',' or '-' expected");
3189 return MatchOperand_ParseFail;
3192 Lex(); // Consume comma or minus
3193 if (Parser.getTok().isNot(AsmToken::Dollar))
3199 SMLoc E = Parser.getTok().getLoc();
3200 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3201 parseMemOperand(Operands);
3202 return MatchOperand_Success;
3205 MipsAsmParser::OperandMatchResultTy
3206 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3207 MCAsmParser &Parser = getParser();
3209 SMLoc S = Parser.getTok().getLoc();
3210 if (parseAnyRegister(Operands) != MatchOperand_Success)
3211 return MatchOperand_ParseFail;
3213 SMLoc E = Parser.getTok().getLoc();
3214 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3215 unsigned Reg = Op.getGPR32Reg();
3216 Operands.pop_back();
3217 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3218 return MatchOperand_Success;
3221 MipsAsmParser::OperandMatchResultTy
3222 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3223 MCAsmParser &Parser = getParser();
3224 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3225 SmallVector<unsigned, 10> Regs;
3227 if (Parser.getTok().isNot(AsmToken::Dollar))
3228 return MatchOperand_ParseFail;
3230 SMLoc S = Parser.getTok().getLoc();
3232 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3233 return MatchOperand_ParseFail;
3235 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3236 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3237 Regs.push_back(RegNo);
3239 SMLoc E = Parser.getTok().getLoc();
3240 if (Parser.getTok().isNot(AsmToken::Comma)) {
3241 Error(E, "',' expected");
3242 return MatchOperand_ParseFail;
3248 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3249 return MatchOperand_ParseFail;
3251 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3252 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3253 Regs.push_back(RegNo);
3255 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3257 return MatchOperand_Success;
3260 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3262 MCSymbolRefExpr::VariantKind VK =
3263 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3264 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3265 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3266 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3267 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3268 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3269 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3270 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3271 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3272 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3273 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3274 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3275 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3276 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3277 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3278 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3279 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3280 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3281 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3282 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3283 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3284 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3285 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3286 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3287 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3288 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3289 .Default(MCSymbolRefExpr::VK_None);
3291 assert(VK != MCSymbolRefExpr::VK_None);
3296 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3298 /// ::= '(', register, ')'
3299 /// handle it before we iterate so we don't get tripped up by the lack of
3301 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3302 MCAsmParser &Parser = getParser();
3303 if (getLexer().is(AsmToken::LParen)) {
3305 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3307 if (parseOperand(Operands, Name)) {
3308 SMLoc Loc = getLexer().getLoc();
3309 Parser.eatToEndOfStatement();
3310 return Error(Loc, "unexpected token in argument list");
3312 if (Parser.getTok().isNot(AsmToken::RParen)) {
3313 SMLoc Loc = getLexer().getLoc();
3314 Parser.eatToEndOfStatement();
3315 return Error(Loc, "unexpected token, expected ')'");
3318 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3324 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3325 /// either one of these.
3326 /// ::= '[', register, ']'
3327 /// ::= '[', integer, ']'
3328 /// handle it before we iterate so we don't get tripped up by the lack of
3330 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3331 OperandVector &Operands) {
3332 MCAsmParser &Parser = getParser();
3333 if (getLexer().is(AsmToken::LBrac)) {
3335 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3337 if (parseOperand(Operands, Name)) {
3338 SMLoc Loc = getLexer().getLoc();
3339 Parser.eatToEndOfStatement();
3340 return Error(Loc, "unexpected token in argument list");
3342 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3343 SMLoc Loc = getLexer().getLoc();
3344 Parser.eatToEndOfStatement();
3345 return Error(Loc, "unexpected token, expected ']'");
3348 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3354 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3355 SMLoc NameLoc, OperandVector &Operands) {
3356 MCAsmParser &Parser = getParser();
3357 DEBUG(dbgs() << "ParseInstruction\n");
3359 // We have reached first instruction, module directive are now forbidden.
3360 getTargetStreamer().forbidModuleDirective();
3362 // Check if we have valid mnemonic
3363 if (!mnemonicIsValid(Name, 0)) {
3364 Parser.eatToEndOfStatement();
3365 return Error(NameLoc, "unknown instruction");
3367 // First operand in MCInst is instruction mnemonic.
3368 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3370 // Read the remaining operands.
3371 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3372 // Read the first operand.
3373 if (parseOperand(Operands, Name)) {
3374 SMLoc Loc = getLexer().getLoc();
3375 Parser.eatToEndOfStatement();
3376 return Error(Loc, "unexpected token in argument list");
3378 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3380 // AFAIK, parenthesis suffixes are never on the first operand
3382 while (getLexer().is(AsmToken::Comma)) {
3383 Parser.Lex(); // Eat the comma.
3384 // Parse and remember the operand.
3385 if (parseOperand(Operands, Name)) {
3386 SMLoc Loc = getLexer().getLoc();
3387 Parser.eatToEndOfStatement();
3388 return Error(Loc, "unexpected token in argument list");
3390 // Parse bracket and parenthesis suffixes before we iterate
3391 if (getLexer().is(AsmToken::LBrac)) {
3392 if (parseBracketSuffix(Name, Operands))
3394 } else if (getLexer().is(AsmToken::LParen) &&
3395 parseParenSuffix(Name, Operands))
3399 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3400 SMLoc Loc = getLexer().getLoc();
3401 Parser.eatToEndOfStatement();
3402 return Error(Loc, "unexpected token in argument list");
3404 Parser.Lex(); // Consume the EndOfStatement.
3408 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3409 MCAsmParser &Parser = getParser();
3410 SMLoc Loc = getLexer().getLoc();
3411 Parser.eatToEndOfStatement();
3412 return Error(Loc, ErrorMsg);
3415 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3416 return Error(Loc, ErrorMsg);
3419 bool MipsAsmParser::parseSetNoAtDirective() {
3420 MCAsmParser &Parser = getParser();
3421 // Line should look like: ".set noat".
3423 // Set the $at register to $0.
3424 AssemblerOptions.back()->setATRegIndex(0);
3426 Parser.Lex(); // Eat "noat".
3428 // If this is not the end of the statement, report an error.
3429 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3430 reportParseError("unexpected token, expected end of statement");
3434 getTargetStreamer().emitDirectiveSetNoAt();
3435 Parser.Lex(); // Consume the EndOfStatement.
3439 bool MipsAsmParser::parseSetAtDirective() {
3440 // Line can be: ".set at", which sets $at to $1
3441 // or ".set at=$reg", which sets $at to $reg.
3442 MCAsmParser &Parser = getParser();
3443 Parser.Lex(); // Eat "at".
3445 if (getLexer().is(AsmToken::EndOfStatement)) {
3446 // No register was specified, so we set $at to $1.
3447 AssemblerOptions.back()->setATRegIndex(1);
3449 getTargetStreamer().emitDirectiveSetAt();
3450 Parser.Lex(); // Consume the EndOfStatement.
3454 if (getLexer().isNot(AsmToken::Equal)) {
3455 reportParseError("unexpected token, expected equals sign");
3458 Parser.Lex(); // Eat "=".
3460 if (getLexer().isNot(AsmToken::Dollar)) {
3461 if (getLexer().is(AsmToken::EndOfStatement)) {
3462 reportParseError("no register specified");
3465 reportParseError("unexpected token, expected dollar sign '$'");
3469 Parser.Lex(); // Eat "$".
3471 // Find out what "reg" is.
3473 const AsmToken &Reg = Parser.getTok();
3474 if (Reg.is(AsmToken::Identifier)) {
3475 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3476 } else if (Reg.is(AsmToken::Integer)) {
3477 AtRegNo = Reg.getIntVal();
3479 reportParseError("unexpected token, expected identifier or integer");
3483 // Check if $reg is a valid register. If it is, set $at to $reg.
3484 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3485 reportParseError("invalid register");
3488 Parser.Lex(); // Eat "reg".
3490 // If this is not the end of the statement, report an error.
3491 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3492 reportParseError("unexpected token, expected end of statement");
3496 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3498 Parser.Lex(); // Consume the EndOfStatement.
3502 bool MipsAsmParser::parseSetReorderDirective() {
3503 MCAsmParser &Parser = getParser();
3505 // If this is not the end of the statement, report an error.
3506 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3507 reportParseError("unexpected token, expected end of statement");
3510 AssemblerOptions.back()->setReorder();
3511 getTargetStreamer().emitDirectiveSetReorder();
3512 Parser.Lex(); // Consume the EndOfStatement.
3516 bool MipsAsmParser::parseSetNoReorderDirective() {
3517 MCAsmParser &Parser = getParser();
3519 // If this is not the end of the statement, report an error.
3520 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3521 reportParseError("unexpected token, expected end of statement");
3524 AssemblerOptions.back()->setNoReorder();
3525 getTargetStreamer().emitDirectiveSetNoReorder();
3526 Parser.Lex(); // Consume the EndOfStatement.
3530 bool MipsAsmParser::parseSetMacroDirective() {
3531 MCAsmParser &Parser = getParser();
3533 // If this is not the end of the statement, report an error.
3534 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3535 reportParseError("unexpected token, expected end of statement");
3538 AssemblerOptions.back()->setMacro();
3539 getTargetStreamer().emitDirectiveSetMacro();
3540 Parser.Lex(); // Consume the EndOfStatement.
3544 bool MipsAsmParser::parseSetNoMacroDirective() {
3545 MCAsmParser &Parser = getParser();
3547 // If this is not the end of the statement, report an error.
3548 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3549 reportParseError("unexpected token, expected end of statement");
3552 if (AssemblerOptions.back()->isReorder()) {
3553 reportParseError("`noreorder' must be set before `nomacro'");
3556 AssemblerOptions.back()->setNoMacro();
3557 getTargetStreamer().emitDirectiveSetNoMacro();
3558 Parser.Lex(); // Consume the EndOfStatement.
3562 bool MipsAsmParser::parseSetMsaDirective() {
3563 MCAsmParser &Parser = getParser();
3566 // If this is not the end of the statement, report an error.
3567 if (getLexer().isNot(AsmToken::EndOfStatement))
3568 return reportParseError("unexpected token, expected end of statement");
3570 setFeatureBits(Mips::FeatureMSA, "msa");
3571 getTargetStreamer().emitDirectiveSetMsa();
3575 bool MipsAsmParser::parseSetNoMsaDirective() {
3576 MCAsmParser &Parser = getParser();
3579 // If this is not the end of the statement, report an error.
3580 if (getLexer().isNot(AsmToken::EndOfStatement))
3581 return reportParseError("unexpected token, expected end of statement");
3583 clearFeatureBits(Mips::FeatureMSA, "msa");
3584 getTargetStreamer().emitDirectiveSetNoMsa();
3588 bool MipsAsmParser::parseSetNoDspDirective() {
3589 MCAsmParser &Parser = getParser();
3590 Parser.Lex(); // Eat "nodsp".
3592 // If this is not the end of the statement, report an error.
3593 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3594 reportParseError("unexpected token, expected end of statement");
3598 clearFeatureBits(Mips::FeatureDSP, "dsp");
3599 getTargetStreamer().emitDirectiveSetNoDsp();
3603 bool MipsAsmParser::parseSetMips16Directive() {
3604 MCAsmParser &Parser = getParser();
3605 Parser.Lex(); // Eat "mips16".
3607 // If this is not the end of the statement, report an error.
3608 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3609 reportParseError("unexpected token, expected end of statement");
3613 setFeatureBits(Mips::FeatureMips16, "mips16");
3614 getTargetStreamer().emitDirectiveSetMips16();
3615 Parser.Lex(); // Consume the EndOfStatement.
3619 bool MipsAsmParser::parseSetNoMips16Directive() {
3620 MCAsmParser &Parser = getParser();
3621 Parser.Lex(); // Eat "nomips16".
3623 // If this is not the end of the statement, report an error.
3624 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3625 reportParseError("unexpected token, expected end of statement");
3629 clearFeatureBits(Mips::FeatureMips16, "mips16");
3630 getTargetStreamer().emitDirectiveSetNoMips16();
3631 Parser.Lex(); // Consume the EndOfStatement.
3635 bool MipsAsmParser::parseSetFpDirective() {
3636 MCAsmParser &Parser = getParser();
3637 MipsABIFlagsSection::FpABIKind FpAbiVal;
3638 // Line can be: .set fp=32
3641 Parser.Lex(); // Eat fp token
3642 AsmToken Tok = Parser.getTok();
3643 if (Tok.isNot(AsmToken::Equal)) {
3644 reportParseError("unexpected token, expected equals sign '='");
3647 Parser.Lex(); // Eat '=' token.
3648 Tok = Parser.getTok();
3650 if (!parseFpABIValue(FpAbiVal, ".set"))
3653 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3654 reportParseError("unexpected token, expected end of statement");
3657 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3658 Parser.Lex(); // Consume the EndOfStatement.
3662 bool MipsAsmParser::parseSetPopDirective() {
3663 MCAsmParser &Parser = getParser();
3664 SMLoc Loc = getLexer().getLoc();
3667 if (getLexer().isNot(AsmToken::EndOfStatement))
3668 return reportParseError("unexpected token, expected end of statement");
3670 // Always keep an element on the options "stack" to prevent the user
3671 // from changing the initial options. This is how we remember them.
3672 if (AssemblerOptions.size() == 2)
3673 return reportParseError(Loc, ".set pop with no .set push");
3675 AssemblerOptions.pop_back();
3676 setAvailableFeatures(
3677 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
3678 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
3680 getTargetStreamer().emitDirectiveSetPop();
3684 bool MipsAsmParser::parseSetPushDirective() {
3685 MCAsmParser &Parser = getParser();
3687 if (getLexer().isNot(AsmToken::EndOfStatement))
3688 return reportParseError("unexpected token, expected end of statement");
3690 // Create a copy of the current assembler options environment and push it.
3691 AssemblerOptions.push_back(
3692 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3694 getTargetStreamer().emitDirectiveSetPush();
3698 bool MipsAsmParser::parseSetSoftFloatDirective() {
3699 MCAsmParser &Parser = getParser();
3701 if (getLexer().isNot(AsmToken::EndOfStatement))
3702 return reportParseError("unexpected token, expected end of statement");
3704 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3705 getTargetStreamer().emitDirectiveSetSoftFloat();
3709 bool MipsAsmParser::parseSetHardFloatDirective() {
3710 MCAsmParser &Parser = getParser();
3712 if (getLexer().isNot(AsmToken::EndOfStatement))
3713 return reportParseError("unexpected token, expected end of statement");
3715 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3716 getTargetStreamer().emitDirectiveSetHardFloat();
3720 bool MipsAsmParser::parseSetAssignment() {
3722 const MCExpr *Value;
3723 MCAsmParser &Parser = getParser();
3725 if (Parser.parseIdentifier(Name))
3726 reportParseError("expected identifier after .set");
3728 if (getLexer().isNot(AsmToken::Comma))
3729 return reportParseError("unexpected token, expected comma");
3732 if (Parser.parseExpression(Value))
3733 return reportParseError("expected valid expression after comma");
3735 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3736 Sym->setVariableValue(Value);
3741 bool MipsAsmParser::parseSetMips0Directive() {
3742 MCAsmParser &Parser = getParser();
3744 if (getLexer().isNot(AsmToken::EndOfStatement))
3745 return reportParseError("unexpected token, expected end of statement");
3747 // Reset assembler options to their initial values.
3748 setAvailableFeatures(
3749 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
3750 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
3751 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3753 getTargetStreamer().emitDirectiveSetMips0();
3757 bool MipsAsmParser::parseSetArchDirective() {
3758 MCAsmParser &Parser = getParser();
3760 if (getLexer().isNot(AsmToken::Equal))
3761 return reportParseError("unexpected token, expected equals sign");
3765 if (Parser.parseIdentifier(Arch))
3766 return reportParseError("expected arch identifier");
3768 StringRef ArchFeatureName =
3769 StringSwitch<StringRef>(Arch)
3770 .Case("mips1", "mips1")
3771 .Case("mips2", "mips2")
3772 .Case("mips3", "mips3")
3773 .Case("mips4", "mips4")
3774 .Case("mips5", "mips5")
3775 .Case("mips32", "mips32")
3776 .Case("mips32r2", "mips32r2")
3777 .Case("mips32r3", "mips32r3")
3778 .Case("mips32r5", "mips32r5")
3779 .Case("mips32r6", "mips32r6")
3780 .Case("mips64", "mips64")
3781 .Case("mips64r2", "mips64r2")
3782 .Case("mips64r3", "mips64r3")
3783 .Case("mips64r5", "mips64r5")
3784 .Case("mips64r6", "mips64r6")
3785 .Case("cnmips", "cnmips")
3786 .Case("r4000", "mips3") // This is an implementation of Mips3.
3789 if (ArchFeatureName.empty())
3790 return reportParseError("unsupported architecture");
3792 selectArch(ArchFeatureName);
3793 getTargetStreamer().emitDirectiveSetArch(Arch);
3797 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3798 MCAsmParser &Parser = getParser();
3800 if (getLexer().isNot(AsmToken::EndOfStatement))
3801 return reportParseError("unexpected token, expected end of statement");
3805 llvm_unreachable("Unimplemented feature");
3806 case Mips::FeatureDSP:
3807 setFeatureBits(Mips::FeatureDSP, "dsp");
3808 getTargetStreamer().emitDirectiveSetDsp();
3810 case Mips::FeatureMicroMips:
3811 getTargetStreamer().emitDirectiveSetMicroMips();
3813 case Mips::FeatureMips1:
3814 selectArch("mips1");
3815 getTargetStreamer().emitDirectiveSetMips1();
3817 case Mips::FeatureMips2:
3818 selectArch("mips2");
3819 getTargetStreamer().emitDirectiveSetMips2();
3821 case Mips::FeatureMips3:
3822 selectArch("mips3");
3823 getTargetStreamer().emitDirectiveSetMips3();
3825 case Mips::FeatureMips4:
3826 selectArch("mips4");
3827 getTargetStreamer().emitDirectiveSetMips4();
3829 case Mips::FeatureMips5:
3830 selectArch("mips5");
3831 getTargetStreamer().emitDirectiveSetMips5();
3833 case Mips::FeatureMips32:
3834 selectArch("mips32");
3835 getTargetStreamer().emitDirectiveSetMips32();
3837 case Mips::FeatureMips32r2:
3838 selectArch("mips32r2");
3839 getTargetStreamer().emitDirectiveSetMips32R2();
3841 case Mips::FeatureMips32r3:
3842 selectArch("mips32r3");
3843 getTargetStreamer().emitDirectiveSetMips32R3();
3845 case Mips::FeatureMips32r5:
3846 selectArch("mips32r5");
3847 getTargetStreamer().emitDirectiveSetMips32R5();
3849 case Mips::FeatureMips32r6:
3850 selectArch("mips32r6");
3851 getTargetStreamer().emitDirectiveSetMips32R6();
3853 case Mips::FeatureMips64:
3854 selectArch("mips64");
3855 getTargetStreamer().emitDirectiveSetMips64();
3857 case Mips::FeatureMips64r2:
3858 selectArch("mips64r2");
3859 getTargetStreamer().emitDirectiveSetMips64R2();
3861 case Mips::FeatureMips64r3:
3862 selectArch("mips64r3");
3863 getTargetStreamer().emitDirectiveSetMips64R3();
3865 case Mips::FeatureMips64r5:
3866 selectArch("mips64r5");
3867 getTargetStreamer().emitDirectiveSetMips64R5();
3869 case Mips::FeatureMips64r6:
3870 selectArch("mips64r6");
3871 getTargetStreamer().emitDirectiveSetMips64R6();
3877 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3878 MCAsmParser &Parser = getParser();
3879 if (getLexer().isNot(AsmToken::Comma)) {
3880 SMLoc Loc = getLexer().getLoc();
3881 Parser.eatToEndOfStatement();
3882 return Error(Loc, ErrorStr);
3885 Parser.Lex(); // Eat the comma.
3889 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3890 if (AssemblerOptions.back()->isReorder())
3891 Warning(Loc, ".cpload should be inside a noreorder section");
3893 if (inMips16Mode()) {
3894 reportParseError(".cpload is not supported in Mips16 mode");
3898 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3899 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3900 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3901 reportParseError("expected register containing function address");
3905 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3906 if (!RegOpnd.isGPRAsmReg()) {
3907 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3911 // If this is not the end of the statement, report an error.
3912 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3913 reportParseError("unexpected token, expected end of statement");
3917 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3921 bool MipsAsmParser::parseDirectiveCPSetup() {
3922 MCAsmParser &Parser = getParser();
3925 bool SaveIsReg = true;
3927 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3928 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3929 if (ResTy == MatchOperand_NoMatch) {
3930 reportParseError("expected register containing function address");
3931 Parser.eatToEndOfStatement();
3935 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3936 if (!FuncRegOpnd.isGPRAsmReg()) {
3937 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3938 Parser.eatToEndOfStatement();
3942 FuncReg = FuncRegOpnd.getGPR32Reg();
3945 if (!eatComma("unexpected token, expected comma"))
3948 ResTy = parseAnyRegister(TmpReg);
3949 if (ResTy == MatchOperand_NoMatch) {
3950 const AsmToken &Tok = Parser.getTok();
3951 if (Tok.is(AsmToken::Integer)) {
3952 Save = Tok.getIntVal();
3956 reportParseError("expected save register or stack offset");
3957 Parser.eatToEndOfStatement();
3961 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3962 if (!SaveOpnd.isGPRAsmReg()) {
3963 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3964 Parser.eatToEndOfStatement();
3967 Save = SaveOpnd.getGPR32Reg();
3970 if (!eatComma("unexpected token, expected comma"))
3974 if (Parser.parseExpression(Expr)) {
3975 reportParseError("expected expression");
3979 if (Expr->getKind() != MCExpr::SymbolRef) {
3980 reportParseError("expected symbol");
3983 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3985 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3990 bool MipsAsmParser::parseDirectiveNaN() {
3991 MCAsmParser &Parser = getParser();
3992 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3993 const AsmToken &Tok = Parser.getTok();
3995 if (Tok.getString() == "2008") {
3997 getTargetStreamer().emitDirectiveNaN2008();
3999 } else if (Tok.getString() == "legacy") {
4001 getTargetStreamer().emitDirectiveNaNLegacy();
4005 // If we don't recognize the option passed to the .nan
4006 // directive (e.g. no option or unknown option), emit an error.
4007 reportParseError("invalid option in .nan directive");
4011 bool MipsAsmParser::parseDirectiveSet() {
4012 MCAsmParser &Parser = getParser();
4013 // Get the next token.
4014 const AsmToken &Tok = Parser.getTok();
4016 if (Tok.getString() == "noat") {
4017 return parseSetNoAtDirective();
4018 } else if (Tok.getString() == "at") {
4019 return parseSetAtDirective();
4020 } else if (Tok.getString() == "arch") {
4021 return parseSetArchDirective();
4022 } else if (Tok.getString() == "fp") {
4023 return parseSetFpDirective();
4024 } else if (Tok.getString() == "pop") {
4025 return parseSetPopDirective();
4026 } else if (Tok.getString() == "push") {
4027 return parseSetPushDirective();
4028 } else if (Tok.getString() == "reorder") {
4029 return parseSetReorderDirective();
4030 } else if (Tok.getString() == "noreorder") {
4031 return parseSetNoReorderDirective();
4032 } else if (Tok.getString() == "macro") {
4033 return parseSetMacroDirective();
4034 } else if (Tok.getString() == "nomacro") {
4035 return parseSetNoMacroDirective();
4036 } else if (Tok.getString() == "mips16") {
4037 return parseSetMips16Directive();
4038 } else if (Tok.getString() == "nomips16") {
4039 return parseSetNoMips16Directive();
4040 } else if (Tok.getString() == "nomicromips") {
4041 getTargetStreamer().emitDirectiveSetNoMicroMips();
4042 Parser.eatToEndOfStatement();
4044 } else if (Tok.getString() == "micromips") {
4045 return parseSetFeature(Mips::FeatureMicroMips);
4046 } else if (Tok.getString() == "mips0") {
4047 return parseSetMips0Directive();
4048 } else if (Tok.getString() == "mips1") {
4049 return parseSetFeature(Mips::FeatureMips1);
4050 } else if (Tok.getString() == "mips2") {
4051 return parseSetFeature(Mips::FeatureMips2);
4052 } else if (Tok.getString() == "mips3") {
4053 return parseSetFeature(Mips::FeatureMips3);
4054 } else if (Tok.getString() == "mips4") {
4055 return parseSetFeature(Mips::FeatureMips4);
4056 } else if (Tok.getString() == "mips5") {
4057 return parseSetFeature(Mips::FeatureMips5);
4058 } else if (Tok.getString() == "mips32") {
4059 return parseSetFeature(Mips::FeatureMips32);
4060 } else if (Tok.getString() == "mips32r2") {
4061 return parseSetFeature(Mips::FeatureMips32r2);
4062 } else if (Tok.getString() == "mips32r3") {
4063 return parseSetFeature(Mips::FeatureMips32r3);
4064 } else if (Tok.getString() == "mips32r5") {
4065 return parseSetFeature(Mips::FeatureMips32r5);
4066 } else if (Tok.getString() == "mips32r6") {
4067 return parseSetFeature(Mips::FeatureMips32r6);
4068 } else if (Tok.getString() == "mips64") {
4069 return parseSetFeature(Mips::FeatureMips64);
4070 } else if (Tok.getString() == "mips64r2") {
4071 return parseSetFeature(Mips::FeatureMips64r2);
4072 } else if (Tok.getString() == "mips64r3") {
4073 return parseSetFeature(Mips::FeatureMips64r3);
4074 } else if (Tok.getString() == "mips64r5") {
4075 return parseSetFeature(Mips::FeatureMips64r5);
4076 } else if (Tok.getString() == "mips64r6") {
4077 return parseSetFeature(Mips::FeatureMips64r6);
4078 } else if (Tok.getString() == "dsp") {
4079 return parseSetFeature(Mips::FeatureDSP);
4080 } else if (Tok.getString() == "nodsp") {
4081 return parseSetNoDspDirective();
4082 } else if (Tok.getString() == "msa") {
4083 return parseSetMsaDirective();
4084 } else if (Tok.getString() == "nomsa") {
4085 return parseSetNoMsaDirective();
4086 } else if (Tok.getString() == "softfloat") {
4087 return parseSetSoftFloatDirective();
4088 } else if (Tok.getString() == "hardfloat") {
4089 return parseSetHardFloatDirective();
4091 // It is just an identifier, look for an assignment.
4092 parseSetAssignment();
4099 /// parseDataDirective
4100 /// ::= .word [ expression (, expression)* ]
4101 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4102 MCAsmParser &Parser = getParser();
4103 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4105 const MCExpr *Value;
4106 if (getParser().parseExpression(Value))
4109 getParser().getStreamer().EmitValue(Value, Size);
4111 if (getLexer().is(AsmToken::EndOfStatement))
4114 if (getLexer().isNot(AsmToken::Comma))
4115 return Error(L, "unexpected token, expected comma");
4124 /// parseDirectiveGpWord
4125 /// ::= .gpword local_sym
4126 bool MipsAsmParser::parseDirectiveGpWord() {
4127 MCAsmParser &Parser = getParser();
4128 const MCExpr *Value;
4129 // EmitGPRel32Value requires an expression, so we are using base class
4130 // method to evaluate the expression.
4131 if (getParser().parseExpression(Value))
4133 getParser().getStreamer().EmitGPRel32Value(Value);
4135 if (getLexer().isNot(AsmToken::EndOfStatement))
4136 return Error(getLexer().getLoc(),
4137 "unexpected token, expected end of statement");
4138 Parser.Lex(); // Eat EndOfStatement token.
4142 /// parseDirectiveGpDWord
4143 /// ::= .gpdword local_sym
4144 bool MipsAsmParser::parseDirectiveGpDWord() {
4145 MCAsmParser &Parser = getParser();
4146 const MCExpr *Value;
4147 // EmitGPRel64Value requires an expression, so we are using base class
4148 // method to evaluate the expression.
4149 if (getParser().parseExpression(Value))
4151 getParser().getStreamer().EmitGPRel64Value(Value);
4153 if (getLexer().isNot(AsmToken::EndOfStatement))
4154 return Error(getLexer().getLoc(),
4155 "unexpected token, expected end of statement");
4156 Parser.Lex(); // Eat EndOfStatement token.
4160 bool MipsAsmParser::parseDirectiveOption() {
4161 MCAsmParser &Parser = getParser();
4162 // Get the option token.
4163 AsmToken Tok = Parser.getTok();
4164 // At the moment only identifiers are supported.
4165 if (Tok.isNot(AsmToken::Identifier)) {
4166 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4167 Parser.eatToEndOfStatement();
4171 StringRef Option = Tok.getIdentifier();
4173 if (Option == "pic0") {
4174 getTargetStreamer().emitDirectiveOptionPic0();
4176 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4177 Error(Parser.getTok().getLoc(),
4178 "unexpected token, expected end of statement");
4179 Parser.eatToEndOfStatement();
4184 if (Option == "pic2") {
4185 getTargetStreamer().emitDirectiveOptionPic2();
4187 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4188 Error(Parser.getTok().getLoc(),
4189 "unexpected token, expected end of statement");
4190 Parser.eatToEndOfStatement();
4196 Warning(Parser.getTok().getLoc(),
4197 "unknown option, expected 'pic0' or 'pic2'");
4198 Parser.eatToEndOfStatement();
4202 /// parseInsnDirective
4204 bool MipsAsmParser::parseInsnDirective() {
4205 // If this is not the end of the statement, report an error.
4206 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4207 reportParseError("unexpected token, expected end of statement");
4211 // The actual label marking happens in
4212 // MipsELFStreamer::createPendingLabelRelocs().
4213 getTargetStreamer().emitDirectiveInsn();
4215 getParser().Lex(); // Eat EndOfStatement token.
4219 /// parseDirectiveModule
4220 /// ::= .module oddspreg
4221 /// ::= .module nooddspreg
4222 /// ::= .module fp=value
4223 bool MipsAsmParser::parseDirectiveModule() {
4224 MCAsmParser &Parser = getParser();
4225 MCAsmLexer &Lexer = getLexer();
4226 SMLoc L = Lexer.getLoc();
4228 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4229 // TODO : get a better message.
4230 reportParseError(".module directive must appear before any code");
4235 if (Parser.parseIdentifier(Option)) {
4236 reportParseError("expected .module option identifier");
4240 if (Option == "oddspreg") {
4241 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4242 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4244 // If this is not the end of the statement, report an error.
4245 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4246 reportParseError("unexpected token, expected end of statement");
4250 return false; // parseDirectiveModule has finished successfully.
4251 } else if (Option == "nooddspreg") {
4253 Error(L, "'.module nooddspreg' requires the O32 ABI");
4257 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4258 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4260 // If this is not the end of the statement, report an error.
4261 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4262 reportParseError("unexpected token, expected end of statement");
4266 return false; // parseDirectiveModule has finished successfully.
4267 } else if (Option == "fp") {
4268 return parseDirectiveModuleFP();
4270 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4274 /// parseDirectiveModuleFP
4278 bool MipsAsmParser::parseDirectiveModuleFP() {
4279 MCAsmParser &Parser = getParser();
4280 MCAsmLexer &Lexer = getLexer();
4282 if (Lexer.isNot(AsmToken::Equal)) {
4283 reportParseError("unexpected token, expected equals sign '='");
4286 Parser.Lex(); // Eat '=' token.
4288 MipsABIFlagsSection::FpABIKind FpABI;
4289 if (!parseFpABIValue(FpABI, ".module"))
4292 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4293 reportParseError("unexpected token, expected end of statement");
4297 // Emit appropriate flags.
4298 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4299 Parser.Lex(); // Consume the EndOfStatement.
4303 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4304 StringRef Directive) {
4305 MCAsmParser &Parser = getParser();
4306 MCAsmLexer &Lexer = getLexer();
4308 if (Lexer.is(AsmToken::Identifier)) {
4309 StringRef Value = Parser.getTok().getString();
4312 if (Value != "xx") {
4313 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4318 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4322 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4326 if (Lexer.is(AsmToken::Integer)) {
4327 unsigned Value = Parser.getTok().getIntVal();
4330 if (Value != 32 && Value != 64) {
4331 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4337 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4341 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4343 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4351 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4352 MCAsmParser &Parser = getParser();
4353 StringRef IDVal = DirectiveID.getString();
4355 if (IDVal == ".cpload")
4356 return parseDirectiveCpLoad(DirectiveID.getLoc());
4357 if (IDVal == ".dword") {
4358 parseDataDirective(8, DirectiveID.getLoc());
4361 if (IDVal == ".ent") {
4362 StringRef SymbolName;
4364 if (Parser.parseIdentifier(SymbolName)) {
4365 reportParseError("expected identifier after .ent");
4369 // There's an undocumented extension that allows an integer to
4370 // follow the name of the procedure which AFAICS is ignored by GAS.
4371 // Example: .ent foo,2
4372 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4373 if (getLexer().isNot(AsmToken::Comma)) {
4374 // Even though we accept this undocumented extension for compatibility
4375 // reasons, the additional integer argument does not actually change
4376 // the behaviour of the '.ent' directive, so we would like to discourage
4377 // its use. We do this by not referring to the extended version in
4378 // error messages which are not directly related to its use.
4379 reportParseError("unexpected token, expected end of statement");
4382 Parser.Lex(); // Eat the comma.
4383 const MCExpr *DummyNumber;
4384 int64_t DummyNumberVal;
4385 // If the user was explicitly trying to use the extended version,
4386 // we still give helpful extension-related error messages.
4387 if (Parser.parseExpression(DummyNumber)) {
4388 reportParseError("expected number after comma");
4391 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4392 reportParseError("expected an absolute expression after comma");
4397 // If this is not the end of the statement, report an error.
4398 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4399 reportParseError("unexpected token, expected end of statement");
4403 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4405 getTargetStreamer().emitDirectiveEnt(*Sym);
4410 if (IDVal == ".end") {
4411 StringRef SymbolName;
4413 if (Parser.parseIdentifier(SymbolName)) {
4414 reportParseError("expected identifier after .end");
4418 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4419 reportParseError("unexpected token, expected end of statement");
4423 if (CurrentFn == nullptr) {
4424 reportParseError(".end used without .ent");
4428 if ((SymbolName != CurrentFn->getName())) {
4429 reportParseError(".end symbol does not match .ent symbol");
4433 getTargetStreamer().emitDirectiveEnd(SymbolName);
4434 CurrentFn = nullptr;
4438 if (IDVal == ".frame") {
4439 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4440 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4441 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4442 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4443 reportParseError("expected stack register");
4447 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4448 if (!StackRegOpnd.isGPRAsmReg()) {
4449 reportParseError(StackRegOpnd.getStartLoc(),
4450 "expected general purpose register");
4453 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4455 if (Parser.getTok().is(AsmToken::Comma))
4458 reportParseError("unexpected token, expected comma");
4462 // Parse the frame size.
4463 const MCExpr *FrameSize;
4464 int64_t FrameSizeVal;
4466 if (Parser.parseExpression(FrameSize)) {
4467 reportParseError("expected frame size value");
4471 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4472 reportParseError("frame size not an absolute expression");
4476 if (Parser.getTok().is(AsmToken::Comma))
4479 reportParseError("unexpected token, expected comma");
4483 // Parse the return register.
4485 ResTy = parseAnyRegister(TmpReg);
4486 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4487 reportParseError("expected return register");
4491 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4492 if (!ReturnRegOpnd.isGPRAsmReg()) {
4493 reportParseError(ReturnRegOpnd.getStartLoc(),
4494 "expected general purpose register");
4498 // If this is not the end of the statement, report an error.
4499 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4500 reportParseError("unexpected token, expected end of statement");
4504 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4505 ReturnRegOpnd.getGPR32Reg());
4509 if (IDVal == ".set") {
4510 return parseDirectiveSet();
4513 if (IDVal == ".mask" || IDVal == ".fmask") {
4514 // .mask bitmask, frame_offset
4515 // bitmask: One bit for each register used.
4516 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4517 // first register is expected to be saved.
4519 // .mask 0x80000000, -4
4520 // .fmask 0x80000000, -4
4523 // Parse the bitmask
4524 const MCExpr *BitMask;
4527 if (Parser.parseExpression(BitMask)) {
4528 reportParseError("expected bitmask value");
4532 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4533 reportParseError("bitmask not an absolute expression");
4537 if (Parser.getTok().is(AsmToken::Comma))
4540 reportParseError("unexpected token, expected comma");
4544 // Parse the frame_offset
4545 const MCExpr *FrameOffset;
4546 int64_t FrameOffsetVal;
4548 if (Parser.parseExpression(FrameOffset)) {
4549 reportParseError("expected frame offset value");
4553 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4554 reportParseError("frame offset not an absolute expression");
4558 // If this is not the end of the statement, report an error.
4559 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4560 reportParseError("unexpected token, expected end of statement");
4564 if (IDVal == ".mask")
4565 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4567 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4571 if (IDVal == ".nan")
4572 return parseDirectiveNaN();
4574 if (IDVal == ".gpword") {
4575 parseDirectiveGpWord();
4579 if (IDVal == ".gpdword") {
4580 parseDirectiveGpDWord();
4584 if (IDVal == ".word") {
4585 parseDataDirective(4, DirectiveID.getLoc());
4589 if (IDVal == ".option")
4590 return parseDirectiveOption();
4592 if (IDVal == ".abicalls") {
4593 getTargetStreamer().emitDirectiveAbiCalls();
4594 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4595 Error(Parser.getTok().getLoc(),
4596 "unexpected token, expected end of statement");
4598 Parser.eatToEndOfStatement();
4603 if (IDVal == ".cpsetup")
4604 return parseDirectiveCPSetup();
4606 if (IDVal == ".module")
4607 return parseDirectiveModule();
4609 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4610 return parseInternalDirectiveReallowModule();
4612 if (IDVal == ".insn")
4613 return parseInsnDirective();
4618 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4619 // If this is not the end of the statement, report an error.
4620 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4621 reportParseError("unexpected token, expected end of statement");
4625 getTargetStreamer().reallowModuleDirective();
4627 getParser().Lex(); // Eat EndOfStatement token.
4631 extern "C" void LLVMInitializeMipsAsmParser() {
4632 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4633 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4634 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4635 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4638 #define GET_REGISTER_MATCHER
4639 #define GET_MATCHER_IMPLEMENTATION
4640 #include "MipsGenAsmMatcher.inc"