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 expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
195 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions);
197 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 void expandLoadAddressSym(const MCOperand &DstRegOp, const MCOperand &SymOp,
201 bool Is32BitSym, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions);
204 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
205 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
208 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 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 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1919 const MCOperand &SrcRegOp = Inst.getOperand(1);
1920 assert(SrcRegOp.isReg() && "expected register operand kind");
1922 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1923 Is32BitImm, IDLoc, Instructions))
1930 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1931 SmallVectorImpl<MCInst> &Instructions) {
1932 const MCOperand &DstRegOp = Inst.getOperand(0);
1933 assert(DstRegOp.isReg() && "expected register operand kind");
1935 const MCOperand &ImmOp = Inst.getOperand(1);
1936 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1937 "expected immediate operand kind");
1938 if (!ImmOp.isImm()) {
1939 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1943 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1944 Is32BitImm, IDLoc, Instructions))
1950 void MipsAsmParser::expandLoadAddressSym(
1951 const MCOperand &DstRegOp, const MCOperand &SymOp, bool Is32BitSym,
1952 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1953 warnIfNoMacro(IDLoc);
1955 if (Is32BitSym && isABI_N64())
1956 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1959 unsigned RegNo = DstRegOp.getReg();
1960 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1961 const MCSymbolRefExpr *HiExpr =
1962 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1963 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1964 const MCSymbolRefExpr *LoExpr =
1965 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1966 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1968 // If it's a 64-bit architecture, expand to:
1969 // la d,sym => lui d,highest(sym)
1970 // ori d,d,higher(sym)
1972 // ori d,d,hi16(sym)
1974 // ori d,d,lo16(sym)
1975 const MCSymbolRefExpr *HighestExpr =
1976 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1977 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1978 const MCSymbolRefExpr *HigherExpr =
1979 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1980 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1982 tmpInst.setOpcode(Mips::LUi);
1983 tmpInst.addOperand(MCOperand::createReg(RegNo));
1984 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1985 Instructions.push_back(tmpInst);
1987 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), RegNo, SMLoc(),
1989 createLShiftOri<16>(MCOperand::createExpr(HiExpr), RegNo, SMLoc(),
1991 createLShiftOri<16>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1994 // Otherwise, expand to:
1995 // la d,sym => lui d,hi16(sym)
1996 // ori d,d,lo16(sym)
1997 tmpInst.setOpcode(Mips::LUi);
1998 tmpInst.addOperand(MCOperand::createReg(RegNo));
1999 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2000 Instructions.push_back(tmpInst);
2002 createLShiftOri<0>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
2007 bool MipsAsmParser::expandUncondBranchMMPseudo(
2008 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2009 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2010 "unexpected number of operands");
2012 MCOperand Offset = Inst.getOperand(0);
2013 if (Offset.isExpr()) {
2015 Inst.setOpcode(Mips::BEQ_MM);
2016 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2017 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2018 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2020 assert(Offset.isImm() && "expected immediate operand kind");
2021 if (isIntN(11, Offset.getImm())) {
2022 // If offset fits into 11 bits then this instruction becomes microMIPS
2023 // 16-bit unconditional branch instruction.
2024 Inst.setOpcode(Mips::B16_MM);
2026 if (!isIntN(17, Offset.getImm()))
2027 Error(IDLoc, "branch target out of range");
2028 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2029 Error(IDLoc, "branch to misaligned address");
2031 Inst.setOpcode(Mips::BEQ_MM);
2032 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2033 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2034 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2037 Instructions.push_back(Inst);
2039 // If .set reorder is active, emit a NOP after the branch instruction.
2040 if (AssemblerOptions.back()->isReorder())
2041 createNop(true, IDLoc, Instructions);
2046 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2047 SmallVectorImpl<MCInst> &Instructions) {
2048 const MCOperand &DstRegOp = Inst.getOperand(0);
2049 assert(DstRegOp.isReg() && "expected register operand kind");
2051 const MCOperand &ImmOp = Inst.getOperand(1);
2052 assert(ImmOp.isImm() && "expected immediate operand kind");
2054 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2055 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2057 unsigned OpCode = 0;
2058 switch(Inst.getOpcode()) {
2066 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2070 int64_t ImmValue = ImmOp.getImm();
2071 if (ImmValue == 0) {
2073 BranchInst.setOpcode(OpCode);
2074 BranchInst.addOperand(DstRegOp);
2075 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2076 BranchInst.addOperand(MemOffsetOp);
2077 Instructions.push_back(BranchInst);
2079 warnIfNoMacro(IDLoc);
2081 unsigned ATReg = getATReg(IDLoc);
2085 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2090 BranchInst.setOpcode(OpCode);
2091 BranchInst.addOperand(DstRegOp);
2092 BranchInst.addOperand(MCOperand::createReg(ATReg));
2093 BranchInst.addOperand(MemOffsetOp);
2094 Instructions.push_back(BranchInst);
2099 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2100 SmallVectorImpl<MCInst> &Instructions,
2101 bool isLoad, bool isImmOpnd) {
2102 const MCSymbolRefExpr *SR;
2104 unsigned ImmOffset, HiOffset, LoOffset;
2105 const MCExpr *ExprOffset;
2107 // 1st operand is either the source or destination register.
2108 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2109 unsigned RegOpNum = Inst.getOperand(0).getReg();
2110 // 2nd operand is the base register.
2111 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2112 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2113 // 3rd operand is either an immediate or expression.
2115 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2116 ImmOffset = Inst.getOperand(2).getImm();
2117 LoOffset = ImmOffset & 0x0000ffff;
2118 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2119 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2120 if (LoOffset & 0x8000)
2123 ExprOffset = Inst.getOperand(2).getExpr();
2124 // All instructions will have the same location.
2125 TempInst.setLoc(IDLoc);
2126 // These are some of the types of expansions we perform here:
2127 // 1) lw $8, sym => lui $8, %hi(sym)
2128 // lw $8, %lo(sym)($8)
2129 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2131 // lw $8, %lo(offset)($9)
2132 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2134 // lw $8, %lo(offset)($at)
2135 // 4) sw $8, sym => lui $at, %hi(sym)
2136 // sw $8, %lo(sym)($at)
2137 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2139 // sw $8, %lo(offset)($at)
2140 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2141 // ldc1 $f0, %lo(sym)($at)
2143 // For load instructions we can use the destination register as a temporary
2144 // if base and dst are different (examples 1 and 2) and if the base register
2145 // is general purpose otherwise we must use $at (example 6) and error if it's
2146 // not available. For stores we must use $at (examples 4 and 5) because we
2147 // must not clobber the source register setting up the offset.
2148 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2149 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2150 unsigned RegClassIDOp0 =
2151 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2152 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2153 (RegClassIDOp0 == Mips::GPR64RegClassID);
2154 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2155 TmpRegNum = RegOpNum;
2157 // At this point we need AT to perform the expansions and we exit if it is
2159 TmpRegNum = getATReg(IDLoc);
2164 TempInst.setOpcode(Mips::LUi);
2165 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2167 TempInst.addOperand(MCOperand::createImm(HiOffset));
2169 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2170 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2171 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2172 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2174 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2176 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2177 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2180 // Add the instruction to the list.
2181 Instructions.push_back(TempInst);
2182 // Prepare TempInst for next instruction.
2184 // Add temp register to base.
2185 if (BaseRegNum != Mips::ZERO) {
2186 TempInst.setOpcode(Mips::ADDu);
2187 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2188 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2189 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2190 Instructions.push_back(TempInst);
2193 // And finally, create original instruction with low part
2194 // of offset and new base.
2195 TempInst.setOpcode(Inst.getOpcode());
2196 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2197 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2199 TempInst.addOperand(MCOperand::createImm(LoOffset));
2201 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2202 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2203 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2205 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2207 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2208 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2211 Instructions.push_back(TempInst);
2216 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2217 SmallVectorImpl<MCInst> &Instructions) {
2218 unsigned OpNum = Inst.getNumOperands();
2219 unsigned Opcode = Inst.getOpcode();
2220 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2222 assert (Inst.getOperand(OpNum - 1).isImm() &&
2223 Inst.getOperand(OpNum - 2).isReg() &&
2224 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2226 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2227 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2228 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2229 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2230 // It can be implemented as SWM16 or LWM16 instruction.
2231 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2233 Inst.setOpcode(NewOpcode);
2234 Instructions.push_back(Inst);
2238 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2239 SmallVectorImpl<MCInst> &Instructions) {
2241 if (hasShortDelaySlot) {
2242 NopInst.setOpcode(Mips::MOVE16_MM);
2243 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2244 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2246 NopInst.setOpcode(Mips::SLL);
2247 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2248 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2249 NopInst.addOperand(MCOperand::createImm(0));
2251 Instructions.push_back(NopInst);
2254 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2256 SmallVectorImpl<MCInst> &Instructions) {
2258 AdduInst.setOpcode(Mips::ADDu);
2259 AdduInst.addOperand(MCOperand::createReg(DstReg));
2260 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2261 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2262 Instructions.push_back(AdduInst);
2265 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2266 // As described by the Mips32r2 spec, the registers Rd and Rs for
2267 // jalr.hb must be different.
2268 unsigned Opcode = Inst.getOpcode();
2270 if (Opcode == Mips::JALR_HB &&
2271 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2272 return Match_RequiresDifferentSrcAndDst;
2274 return Match_Success;
2277 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2278 OperandVector &Operands,
2280 uint64_t &ErrorInfo,
2281 bool MatchingInlineAsm) {
2284 SmallVector<MCInst, 8> Instructions;
2285 unsigned MatchResult =
2286 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2288 switch (MatchResult) {
2289 case Match_Success: {
2290 if (processInstruction(Inst, IDLoc, Instructions))
2292 for (unsigned i = 0; i < Instructions.size(); i++)
2293 Out.EmitInstruction(Instructions[i], STI);
2296 case Match_MissingFeature:
2297 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2299 case Match_InvalidOperand: {
2300 SMLoc ErrorLoc = IDLoc;
2301 if (ErrorInfo != ~0ULL) {
2302 if (ErrorInfo >= Operands.size())
2303 return Error(IDLoc, "too few operands for instruction");
2305 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2306 if (ErrorLoc == SMLoc())
2310 return Error(ErrorLoc, "invalid operand for instruction");
2312 case Match_MnemonicFail:
2313 return Error(IDLoc, "invalid instruction");
2314 case Match_RequiresDifferentSrcAndDst:
2315 return Error(IDLoc, "source and destination must be different");
2318 llvm_unreachable("Implement any new match types added!");
2321 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2322 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2323 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2324 ") without \".set noat\"");
2327 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2328 if (!AssemblerOptions.back()->isMacro())
2329 Warning(Loc, "macro instruction expanded into multiple instructions");
2333 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2334 SMRange Range, bool ShowColors) {
2335 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2336 Range, SMFixIt(Range, FixMsg),
2340 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2343 CC = StringSwitch<unsigned>(Name)
2379 if (!(isABI_N32() || isABI_N64()))
2382 if (12 <= CC && CC <= 15) {
2383 // Name is one of t4-t7
2384 AsmToken RegTok = getLexer().peekTok();
2385 SMRange RegRange = RegTok.getLocRange();
2387 StringRef FixedName = StringSwitch<StringRef>(Name)
2393 assert(FixedName != "" && "Register name is not one of t4-t7.");
2395 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2396 "Did you mean $" + FixedName + "?", RegRange);
2399 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2400 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2401 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2402 if (8 <= CC && CC <= 11)
2406 CC = StringSwitch<unsigned>(Name)
2418 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2421 CC = StringSwitch<unsigned>(Name)
2422 .Case("hwr_cpunum", 0)
2423 .Case("hwr_synci_step", 1)
2425 .Case("hwr_ccres", 3)
2426 .Case("hwr_ulr", 29)
2432 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2434 if (Name[0] == 'f') {
2435 StringRef NumString = Name.substr(1);
2437 if (NumString.getAsInteger(10, IntVal))
2438 return -1; // This is not an integer.
2439 if (IntVal > 31) // Maximum index for fpu register.
2446 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2448 if (Name.startswith("fcc")) {
2449 StringRef NumString = Name.substr(3);
2451 if (NumString.getAsInteger(10, IntVal))
2452 return -1; // This is not an integer.
2453 if (IntVal > 7) // There are only 8 fcc registers.
2460 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2462 if (Name.startswith("ac")) {
2463 StringRef NumString = Name.substr(2);
2465 if (NumString.getAsInteger(10, IntVal))
2466 return -1; // This is not an integer.
2467 if (IntVal > 3) // There are only 3 acc registers.
2474 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2477 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2486 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2489 CC = StringSwitch<unsigned>(Name)
2492 .Case("msaaccess", 2)
2494 .Case("msamodify", 4)
2495 .Case("msarequest", 5)
2497 .Case("msaunmap", 7)
2503 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2504 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2506 reportParseError(Loc,
2507 "pseudo-instruction requires $at, which is not available");
2510 unsigned AT = getReg(
2511 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2515 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2516 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2519 unsigned MipsAsmParser::getGPR(int RegNo) {
2520 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2524 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2526 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2529 return getReg(RegClass, RegNum);
2532 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2533 MCAsmParser &Parser = getParser();
2534 DEBUG(dbgs() << "parseOperand\n");
2536 // Check if the current operand has a custom associated parser, if so, try to
2537 // custom parse the operand, or fallback to the general approach.
2538 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2539 if (ResTy == MatchOperand_Success)
2541 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2542 // there was a match, but an error occurred, in which case, just return that
2543 // the operand parsing failed.
2544 if (ResTy == MatchOperand_ParseFail)
2547 DEBUG(dbgs() << ".. Generic Parser\n");
2549 switch (getLexer().getKind()) {
2551 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2553 case AsmToken::Dollar: {
2554 // Parse the register.
2555 SMLoc S = Parser.getTok().getLoc();
2557 // Almost all registers have been parsed by custom parsers. There is only
2558 // one exception to this. $zero (and it's alias $0) will reach this point
2559 // for div, divu, and similar instructions because it is not an operand
2560 // to the instruction definition but an explicit register. Special case
2561 // this situation for now.
2562 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2565 // Maybe it is a symbol reference.
2566 StringRef Identifier;
2567 if (Parser.parseIdentifier(Identifier))
2570 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2571 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2572 // Otherwise create a symbol reference.
2574 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2576 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2579 // Else drop to expression parsing.
2580 case AsmToken::LParen:
2581 case AsmToken::Minus:
2582 case AsmToken::Plus:
2583 case AsmToken::Integer:
2584 case AsmToken::Tilde:
2585 case AsmToken::String: {
2586 DEBUG(dbgs() << ".. generic integer\n");
2587 OperandMatchResultTy ResTy = parseImm(Operands);
2588 return ResTy != MatchOperand_Success;
2590 case AsmToken::Percent: {
2591 // It is a symbol reference or constant expression.
2592 const MCExpr *IdVal;
2593 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2594 if (parseRelocOperand(IdVal))
2597 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2599 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2601 } // case AsmToken::Percent
2602 } // switch(getLexer().getKind())
2606 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2607 StringRef RelocStr) {
2609 // Check the type of the expression.
2610 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2611 // It's a constant, evaluate reloc value.
2613 switch (getVariantKind(RelocStr)) {
2614 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2615 // Get the 1st 16-bits.
2616 Val = MCE->getValue() & 0xffff;
2618 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2619 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2620 // 16 bits being negative.
2621 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2623 case MCSymbolRefExpr::VK_Mips_HIGHER:
2624 // Get the 3rd 16-bits.
2625 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2627 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2628 // Get the 4th 16-bits.
2629 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2632 report_fatal_error("unsupported reloc value");
2634 return MCConstantExpr::create(Val, getContext());
2637 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2638 // It's a symbol, create a symbolic expression from the symbol.
2639 StringRef Symbol = MSRE->getSymbol().getName();
2640 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2641 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
2645 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2646 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2648 // Try to create target expression.
2649 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2650 return MipsMCExpr::create(VK, Expr, getContext());
2652 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2653 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2654 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
2658 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2659 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2660 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
2663 // Just return the original expression.
2667 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2669 switch (Expr->getKind()) {
2670 case MCExpr::Constant:
2672 case MCExpr::SymbolRef:
2673 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2674 case MCExpr::Binary:
2675 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2676 if (!isEvaluated(BE->getLHS()))
2678 return isEvaluated(BE->getRHS());
2681 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2682 case MCExpr::Target:
2688 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2689 MCAsmParser &Parser = getParser();
2690 Parser.Lex(); // Eat the % token.
2691 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2692 if (Tok.isNot(AsmToken::Identifier))
2695 std::string Str = Tok.getIdentifier();
2697 Parser.Lex(); // Eat the identifier.
2698 // Now make an expression from the rest of the operand.
2699 const MCExpr *IdVal;
2702 if (getLexer().getKind() == AsmToken::LParen) {
2704 Parser.Lex(); // Eat the '(' token.
2705 if (getLexer().getKind() == AsmToken::Percent) {
2706 Parser.Lex(); // Eat the % token.
2707 const AsmToken &nextTok = Parser.getTok();
2708 if (nextTok.isNot(AsmToken::Identifier))
2711 Str += nextTok.getIdentifier();
2712 Parser.Lex(); // Eat the identifier.
2713 if (getLexer().getKind() != AsmToken::LParen)
2718 if (getParser().parseParenExpression(IdVal, EndLoc))
2721 while (getLexer().getKind() == AsmToken::RParen)
2722 Parser.Lex(); // Eat the ')' token.
2725 return true; // Parenthesis must follow the relocation operand.
2727 Res = evaluateRelocExpr(IdVal, Str);
2731 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2733 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2734 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2735 if (ResTy == MatchOperand_Success) {
2736 assert(Operands.size() == 1);
2737 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2738 StartLoc = Operand.getStartLoc();
2739 EndLoc = Operand.getEndLoc();
2741 // AFAIK, we only support numeric registers and named GPR's in CFI
2743 // Don't worry about eating tokens before failing. Using an unrecognised
2744 // register is a parse error.
2745 if (Operand.isGPRAsmReg()) {
2746 // Resolve to GPR32 or GPR64 appropriately.
2747 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2750 return (RegNo == (unsigned)-1);
2753 assert(Operands.size() == 0);
2754 return (RegNo == (unsigned)-1);
2757 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2758 MCAsmParser &Parser = getParser();
2762 while (getLexer().getKind() == AsmToken::LParen)
2765 switch (getLexer().getKind()) {
2768 case AsmToken::Identifier:
2769 case AsmToken::LParen:
2770 case AsmToken::Integer:
2771 case AsmToken::Minus:
2772 case AsmToken::Plus:
2774 Result = getParser().parseParenExpression(Res, S);
2776 Result = (getParser().parseExpression(Res));
2777 while (getLexer().getKind() == AsmToken::RParen)
2780 case AsmToken::Percent:
2781 Result = parseRelocOperand(Res);
2786 MipsAsmParser::OperandMatchResultTy
2787 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2788 MCAsmParser &Parser = getParser();
2789 DEBUG(dbgs() << "parseMemOperand\n");
2790 const MCExpr *IdVal = nullptr;
2792 bool isParenExpr = false;
2793 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2794 // First operand is the offset.
2795 S = Parser.getTok().getLoc();
2797 if (getLexer().getKind() == AsmToken::LParen) {
2802 if (getLexer().getKind() != AsmToken::Dollar) {
2803 if (parseMemOffset(IdVal, isParenExpr))
2804 return MatchOperand_ParseFail;
2806 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2807 if (Tok.isNot(AsmToken::LParen)) {
2808 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2809 if (Mnemonic.getToken() == "la") {
2811 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2812 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2813 return MatchOperand_Success;
2815 if (Tok.is(AsmToken::EndOfStatement)) {
2817 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2819 // Zero register assumed, add a memory operand with ZERO as its base.
2820 // "Base" will be managed by k_Memory.
2821 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2824 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2825 return MatchOperand_Success;
2827 Error(Parser.getTok().getLoc(), "'(' expected");
2828 return MatchOperand_ParseFail;
2831 Parser.Lex(); // Eat the '(' token.
2834 Res = parseAnyRegister(Operands);
2835 if (Res != MatchOperand_Success)
2838 if (Parser.getTok().isNot(AsmToken::RParen)) {
2839 Error(Parser.getTok().getLoc(), "')' expected");
2840 return MatchOperand_ParseFail;
2843 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2845 Parser.Lex(); // Eat the ')' token.
2848 IdVal = MCConstantExpr::create(0, getContext());
2850 // Replace the register operand with the memory operand.
2851 std::unique_ptr<MipsOperand> op(
2852 static_cast<MipsOperand *>(Operands.back().release()));
2853 // Remove the register from the operands.
2854 // "op" will be managed by k_Memory.
2855 Operands.pop_back();
2856 // Add the memory operand.
2857 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2859 if (IdVal->evaluateAsAbsolute(Imm))
2860 IdVal = MCConstantExpr::create(Imm, getContext());
2861 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2862 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2866 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2867 return MatchOperand_Success;
2870 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2871 MCAsmParser &Parser = getParser();
2872 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
2874 SMLoc S = Parser.getTok().getLoc();
2876 if (Sym->isVariable())
2877 Expr = Sym->getVariableValue();
2880 if (Expr->getKind() == MCExpr::SymbolRef) {
2881 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2882 StringRef DefSymbol = Ref->getSymbol().getName();
2883 if (DefSymbol.startswith("$")) {
2884 OperandMatchResultTy ResTy =
2885 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2886 if (ResTy == MatchOperand_Success) {
2889 } else if (ResTy == MatchOperand_ParseFail)
2890 llvm_unreachable("Should never ParseFail");
2893 } else if (Expr->getKind() == MCExpr::Constant) {
2895 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2897 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2904 MipsAsmParser::OperandMatchResultTy
2905 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2906 StringRef Identifier,
2908 int Index = matchCPURegisterName(Identifier);
2910 Operands.push_back(MipsOperand::createGPRReg(
2911 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2912 return MatchOperand_Success;
2915 Index = matchHWRegsRegisterName(Identifier);
2917 Operands.push_back(MipsOperand::createHWRegsReg(
2918 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2919 return MatchOperand_Success;
2922 Index = matchFPURegisterName(Identifier);
2924 Operands.push_back(MipsOperand::createFGRReg(
2925 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2926 return MatchOperand_Success;
2929 Index = matchFCCRegisterName(Identifier);
2931 Operands.push_back(MipsOperand::createFCCReg(
2932 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2933 return MatchOperand_Success;
2936 Index = matchACRegisterName(Identifier);
2938 Operands.push_back(MipsOperand::createACCReg(
2939 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2940 return MatchOperand_Success;
2943 Index = matchMSA128RegisterName(Identifier);
2945 Operands.push_back(MipsOperand::createMSA128Reg(
2946 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2947 return MatchOperand_Success;
2950 Index = matchMSA128CtrlRegisterName(Identifier);
2952 Operands.push_back(MipsOperand::createMSACtrlReg(
2953 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2954 return MatchOperand_Success;
2957 return MatchOperand_NoMatch;
2960 MipsAsmParser::OperandMatchResultTy
2961 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2962 MCAsmParser &Parser = getParser();
2963 auto Token = Parser.getLexer().peekTok(false);
2965 if (Token.is(AsmToken::Identifier)) {
2966 DEBUG(dbgs() << ".. identifier\n");
2967 StringRef Identifier = Token.getIdentifier();
2968 OperandMatchResultTy ResTy =
2969 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2971 } else if (Token.is(AsmToken::Integer)) {
2972 DEBUG(dbgs() << ".. integer\n");
2973 Operands.push_back(MipsOperand::createNumericReg(
2974 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2976 return MatchOperand_Success;
2979 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2981 return MatchOperand_NoMatch;
2984 MipsAsmParser::OperandMatchResultTy
2985 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2986 MCAsmParser &Parser = getParser();
2987 DEBUG(dbgs() << "parseAnyRegister\n");
2989 auto Token = Parser.getTok();
2991 SMLoc S = Token.getLoc();
2993 if (Token.isNot(AsmToken::Dollar)) {
2994 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2995 if (Token.is(AsmToken::Identifier)) {
2996 if (searchSymbolAlias(Operands))
2997 return MatchOperand_Success;
2999 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3000 return MatchOperand_NoMatch;
3002 DEBUG(dbgs() << ".. $\n");
3004 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3005 if (ResTy == MatchOperand_Success) {
3007 Parser.Lex(); // identifier
3012 MipsAsmParser::OperandMatchResultTy
3013 MipsAsmParser::parseImm(OperandVector &Operands) {
3014 MCAsmParser &Parser = getParser();
3015 switch (getLexer().getKind()) {
3017 return MatchOperand_NoMatch;
3018 case AsmToken::LParen:
3019 case AsmToken::Minus:
3020 case AsmToken::Plus:
3021 case AsmToken::Integer:
3022 case AsmToken::Tilde:
3023 case AsmToken::String:
3027 const MCExpr *IdVal;
3028 SMLoc S = Parser.getTok().getLoc();
3029 if (getParser().parseExpression(IdVal))
3030 return MatchOperand_ParseFail;
3032 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3033 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3034 return MatchOperand_Success;
3037 MipsAsmParser::OperandMatchResultTy
3038 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3039 MCAsmParser &Parser = getParser();
3040 DEBUG(dbgs() << "parseJumpTarget\n");
3042 SMLoc S = getLexer().getLoc();
3044 // Integers and expressions are acceptable
3045 OperandMatchResultTy ResTy = parseImm(Operands);
3046 if (ResTy != MatchOperand_NoMatch)
3049 // Registers are a valid target and have priority over symbols.
3050 ResTy = parseAnyRegister(Operands);
3051 if (ResTy != MatchOperand_NoMatch)
3054 const MCExpr *Expr = nullptr;
3055 if (Parser.parseExpression(Expr)) {
3056 // We have no way of knowing if a symbol was consumed so we must ParseFail
3057 return MatchOperand_ParseFail;
3060 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3061 return MatchOperand_Success;
3064 MipsAsmParser::OperandMatchResultTy
3065 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3066 MCAsmParser &Parser = getParser();
3067 const MCExpr *IdVal;
3068 // If the first token is '$' we may have register operand.
3069 if (Parser.getTok().is(AsmToken::Dollar))
3070 return MatchOperand_NoMatch;
3071 SMLoc S = Parser.getTok().getLoc();
3072 if (getParser().parseExpression(IdVal))
3073 return MatchOperand_ParseFail;
3074 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3075 assert(MCE && "Unexpected MCExpr type.");
3076 int64_t Val = MCE->getValue();
3077 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3078 Operands.push_back(MipsOperand::CreateImm(
3079 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3080 return MatchOperand_Success;
3083 MipsAsmParser::OperandMatchResultTy
3084 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3085 MCAsmParser &Parser = getParser();
3086 switch (getLexer().getKind()) {
3088 return MatchOperand_NoMatch;
3089 case AsmToken::LParen:
3090 case AsmToken::Plus:
3091 case AsmToken::Minus:
3092 case AsmToken::Integer:
3097 SMLoc S = Parser.getTok().getLoc();
3099 if (getParser().parseExpression(Expr))
3100 return MatchOperand_ParseFail;
3103 if (!Expr->evaluateAsAbsolute(Val)) {
3104 Error(S, "expected immediate value");
3105 return MatchOperand_ParseFail;
3108 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3109 // and because the CPU always adds one to the immediate field, the allowed
3110 // range becomes 1..4. We'll only check the range here and will deal
3111 // with the addition/subtraction when actually decoding/encoding
3113 if (Val < 1 || Val > 4) {
3114 Error(S, "immediate not in range (1..4)");
3115 return MatchOperand_ParseFail;
3119 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3120 return MatchOperand_Success;
3123 MipsAsmParser::OperandMatchResultTy
3124 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3125 MCAsmParser &Parser = getParser();
3126 SmallVector<unsigned, 10> Regs;
3128 unsigned PrevReg = Mips::NoRegister;
3129 bool RegRange = false;
3130 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3132 if (Parser.getTok().isNot(AsmToken::Dollar))
3133 return MatchOperand_ParseFail;
3135 SMLoc S = Parser.getTok().getLoc();
3136 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3137 SMLoc E = getLexer().getLoc();
3138 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3139 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3141 // Remove last register operand because registers from register range
3142 // should be inserted first.
3143 if (RegNo == Mips::RA) {
3144 Regs.push_back(RegNo);
3146 unsigned TmpReg = PrevReg + 1;
3147 while (TmpReg <= RegNo) {
3148 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3149 Error(E, "invalid register operand");
3150 return MatchOperand_ParseFail;
3154 Regs.push_back(TmpReg++);
3160 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3161 (RegNo != Mips::RA)) {
3162 Error(E, "$16 or $31 expected");
3163 return MatchOperand_ParseFail;
3164 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3165 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3166 Error(E, "invalid register operand");
3167 return MatchOperand_ParseFail;
3168 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3169 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3170 Error(E, "consecutive register numbers expected");
3171 return MatchOperand_ParseFail;
3174 Regs.push_back(RegNo);
3177 if (Parser.getTok().is(AsmToken::Minus))
3180 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3181 !Parser.getTok().isNot(AsmToken::Comma)) {
3182 Error(E, "',' or '-' expected");
3183 return MatchOperand_ParseFail;
3186 Lex(); // Consume comma or minus
3187 if (Parser.getTok().isNot(AsmToken::Dollar))
3193 SMLoc E = Parser.getTok().getLoc();
3194 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3195 parseMemOperand(Operands);
3196 return MatchOperand_Success;
3199 MipsAsmParser::OperandMatchResultTy
3200 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3201 MCAsmParser &Parser = getParser();
3203 SMLoc S = Parser.getTok().getLoc();
3204 if (parseAnyRegister(Operands) != MatchOperand_Success)
3205 return MatchOperand_ParseFail;
3207 SMLoc E = Parser.getTok().getLoc();
3208 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3209 unsigned Reg = Op.getGPR32Reg();
3210 Operands.pop_back();
3211 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3212 return MatchOperand_Success;
3215 MipsAsmParser::OperandMatchResultTy
3216 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3217 MCAsmParser &Parser = getParser();
3218 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3219 SmallVector<unsigned, 10> Regs;
3221 if (Parser.getTok().isNot(AsmToken::Dollar))
3222 return MatchOperand_ParseFail;
3224 SMLoc S = Parser.getTok().getLoc();
3226 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3227 return MatchOperand_ParseFail;
3229 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3230 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3231 Regs.push_back(RegNo);
3233 SMLoc E = Parser.getTok().getLoc();
3234 if (Parser.getTok().isNot(AsmToken::Comma)) {
3235 Error(E, "',' expected");
3236 return MatchOperand_ParseFail;
3242 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3243 return MatchOperand_ParseFail;
3245 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3246 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3247 Regs.push_back(RegNo);
3249 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3251 return MatchOperand_Success;
3254 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3256 MCSymbolRefExpr::VariantKind VK =
3257 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3258 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3259 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3260 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3261 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3262 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3263 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3264 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3265 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3266 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3267 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3268 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3269 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3270 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3271 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3272 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3273 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3274 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3275 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3276 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3277 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3278 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3279 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3280 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3281 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3282 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3283 .Default(MCSymbolRefExpr::VK_None);
3285 assert(VK != MCSymbolRefExpr::VK_None);
3290 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3292 /// ::= '(', register, ')'
3293 /// handle it before we iterate so we don't get tripped up by the lack of
3295 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3296 MCAsmParser &Parser = getParser();
3297 if (getLexer().is(AsmToken::LParen)) {
3299 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3301 if (parseOperand(Operands, Name)) {
3302 SMLoc Loc = getLexer().getLoc();
3303 Parser.eatToEndOfStatement();
3304 return Error(Loc, "unexpected token in argument list");
3306 if (Parser.getTok().isNot(AsmToken::RParen)) {
3307 SMLoc Loc = getLexer().getLoc();
3308 Parser.eatToEndOfStatement();
3309 return Error(Loc, "unexpected token, expected ')'");
3312 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3318 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3319 /// either one of these.
3320 /// ::= '[', register, ']'
3321 /// ::= '[', integer, ']'
3322 /// handle it before we iterate so we don't get tripped up by the lack of
3324 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3325 OperandVector &Operands) {
3326 MCAsmParser &Parser = getParser();
3327 if (getLexer().is(AsmToken::LBrac)) {
3329 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3331 if (parseOperand(Operands, Name)) {
3332 SMLoc Loc = getLexer().getLoc();
3333 Parser.eatToEndOfStatement();
3334 return Error(Loc, "unexpected token in argument list");
3336 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3337 SMLoc Loc = getLexer().getLoc();
3338 Parser.eatToEndOfStatement();
3339 return Error(Loc, "unexpected token, expected ']'");
3342 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3348 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3349 SMLoc NameLoc, OperandVector &Operands) {
3350 MCAsmParser &Parser = getParser();
3351 DEBUG(dbgs() << "ParseInstruction\n");
3353 // We have reached first instruction, module directive are now forbidden.
3354 getTargetStreamer().forbidModuleDirective();
3356 // Check if we have valid mnemonic
3357 if (!mnemonicIsValid(Name, 0)) {
3358 Parser.eatToEndOfStatement();
3359 return Error(NameLoc, "unknown instruction");
3361 // First operand in MCInst is instruction mnemonic.
3362 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3364 // Read the remaining operands.
3365 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3366 // Read the first operand.
3367 if (parseOperand(Operands, Name)) {
3368 SMLoc Loc = getLexer().getLoc();
3369 Parser.eatToEndOfStatement();
3370 return Error(Loc, "unexpected token in argument list");
3372 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3374 // AFAIK, parenthesis suffixes are never on the first operand
3376 while (getLexer().is(AsmToken::Comma)) {
3377 Parser.Lex(); // Eat the comma.
3378 // Parse and remember the operand.
3379 if (parseOperand(Operands, Name)) {
3380 SMLoc Loc = getLexer().getLoc();
3381 Parser.eatToEndOfStatement();
3382 return Error(Loc, "unexpected token in argument list");
3384 // Parse bracket and parenthesis suffixes before we iterate
3385 if (getLexer().is(AsmToken::LBrac)) {
3386 if (parseBracketSuffix(Name, Operands))
3388 } else if (getLexer().is(AsmToken::LParen) &&
3389 parseParenSuffix(Name, Operands))
3393 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3394 SMLoc Loc = getLexer().getLoc();
3395 Parser.eatToEndOfStatement();
3396 return Error(Loc, "unexpected token in argument list");
3398 Parser.Lex(); // Consume the EndOfStatement.
3402 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3403 MCAsmParser &Parser = getParser();
3404 SMLoc Loc = getLexer().getLoc();
3405 Parser.eatToEndOfStatement();
3406 return Error(Loc, ErrorMsg);
3409 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3410 return Error(Loc, ErrorMsg);
3413 bool MipsAsmParser::parseSetNoAtDirective() {
3414 MCAsmParser &Parser = getParser();
3415 // Line should look like: ".set noat".
3417 // Set the $at register to $0.
3418 AssemblerOptions.back()->setATRegIndex(0);
3420 Parser.Lex(); // Eat "noat".
3422 // If this is not the end of the statement, report an error.
3423 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3424 reportParseError("unexpected token, expected end of statement");
3428 getTargetStreamer().emitDirectiveSetNoAt();
3429 Parser.Lex(); // Consume the EndOfStatement.
3433 bool MipsAsmParser::parseSetAtDirective() {
3434 // Line can be: ".set at", which sets $at to $1
3435 // or ".set at=$reg", which sets $at to $reg.
3436 MCAsmParser &Parser = getParser();
3437 Parser.Lex(); // Eat "at".
3439 if (getLexer().is(AsmToken::EndOfStatement)) {
3440 // No register was specified, so we set $at to $1.
3441 AssemblerOptions.back()->setATRegIndex(1);
3443 getTargetStreamer().emitDirectiveSetAt();
3444 Parser.Lex(); // Consume the EndOfStatement.
3448 if (getLexer().isNot(AsmToken::Equal)) {
3449 reportParseError("unexpected token, expected equals sign");
3452 Parser.Lex(); // Eat "=".
3454 if (getLexer().isNot(AsmToken::Dollar)) {
3455 if (getLexer().is(AsmToken::EndOfStatement)) {
3456 reportParseError("no register specified");
3459 reportParseError("unexpected token, expected dollar sign '$'");
3463 Parser.Lex(); // Eat "$".
3465 // Find out what "reg" is.
3467 const AsmToken &Reg = Parser.getTok();
3468 if (Reg.is(AsmToken::Identifier)) {
3469 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3470 } else if (Reg.is(AsmToken::Integer)) {
3471 AtRegNo = Reg.getIntVal();
3473 reportParseError("unexpected token, expected identifier or integer");
3477 // Check if $reg is a valid register. If it is, set $at to $reg.
3478 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3479 reportParseError("invalid register");
3482 Parser.Lex(); // Eat "reg".
3484 // If this is not the end of the statement, report an error.
3485 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3486 reportParseError("unexpected token, expected end of statement");
3490 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3492 Parser.Lex(); // Consume the EndOfStatement.
3496 bool MipsAsmParser::parseSetReorderDirective() {
3497 MCAsmParser &Parser = getParser();
3499 // If this is not the end of the statement, report an error.
3500 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3501 reportParseError("unexpected token, expected end of statement");
3504 AssemblerOptions.back()->setReorder();
3505 getTargetStreamer().emitDirectiveSetReorder();
3506 Parser.Lex(); // Consume the EndOfStatement.
3510 bool MipsAsmParser::parseSetNoReorderDirective() {
3511 MCAsmParser &Parser = getParser();
3513 // If this is not the end of the statement, report an error.
3514 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3515 reportParseError("unexpected token, expected end of statement");
3518 AssemblerOptions.back()->setNoReorder();
3519 getTargetStreamer().emitDirectiveSetNoReorder();
3520 Parser.Lex(); // Consume the EndOfStatement.
3524 bool MipsAsmParser::parseSetMacroDirective() {
3525 MCAsmParser &Parser = getParser();
3527 // If this is not the end of the statement, report an error.
3528 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3529 reportParseError("unexpected token, expected end of statement");
3532 AssemblerOptions.back()->setMacro();
3533 getTargetStreamer().emitDirectiveSetMacro();
3534 Parser.Lex(); // Consume the EndOfStatement.
3538 bool MipsAsmParser::parseSetNoMacroDirective() {
3539 MCAsmParser &Parser = getParser();
3541 // If this is not the end of the statement, report an error.
3542 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3543 reportParseError("unexpected token, expected end of statement");
3546 if (AssemblerOptions.back()->isReorder()) {
3547 reportParseError("`noreorder' must be set before `nomacro'");
3550 AssemblerOptions.back()->setNoMacro();
3551 getTargetStreamer().emitDirectiveSetNoMacro();
3552 Parser.Lex(); // Consume the EndOfStatement.
3556 bool MipsAsmParser::parseSetMsaDirective() {
3557 MCAsmParser &Parser = getParser();
3560 // If this is not the end of the statement, report an error.
3561 if (getLexer().isNot(AsmToken::EndOfStatement))
3562 return reportParseError("unexpected token, expected end of statement");
3564 setFeatureBits(Mips::FeatureMSA, "msa");
3565 getTargetStreamer().emitDirectiveSetMsa();
3569 bool MipsAsmParser::parseSetNoMsaDirective() {
3570 MCAsmParser &Parser = getParser();
3573 // If this is not the end of the statement, report an error.
3574 if (getLexer().isNot(AsmToken::EndOfStatement))
3575 return reportParseError("unexpected token, expected end of statement");
3577 clearFeatureBits(Mips::FeatureMSA, "msa");
3578 getTargetStreamer().emitDirectiveSetNoMsa();
3582 bool MipsAsmParser::parseSetNoDspDirective() {
3583 MCAsmParser &Parser = getParser();
3584 Parser.Lex(); // Eat "nodsp".
3586 // If this is not the end of the statement, report an error.
3587 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3588 reportParseError("unexpected token, expected end of statement");
3592 clearFeatureBits(Mips::FeatureDSP, "dsp");
3593 getTargetStreamer().emitDirectiveSetNoDsp();
3597 bool MipsAsmParser::parseSetMips16Directive() {
3598 MCAsmParser &Parser = getParser();
3599 Parser.Lex(); // Eat "mips16".
3601 // If this is not the end of the statement, report an error.
3602 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3603 reportParseError("unexpected token, expected end of statement");
3607 setFeatureBits(Mips::FeatureMips16, "mips16");
3608 getTargetStreamer().emitDirectiveSetMips16();
3609 Parser.Lex(); // Consume the EndOfStatement.
3613 bool MipsAsmParser::parseSetNoMips16Directive() {
3614 MCAsmParser &Parser = getParser();
3615 Parser.Lex(); // Eat "nomips16".
3617 // If this is not the end of the statement, report an error.
3618 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3619 reportParseError("unexpected token, expected end of statement");
3623 clearFeatureBits(Mips::FeatureMips16, "mips16");
3624 getTargetStreamer().emitDirectiveSetNoMips16();
3625 Parser.Lex(); // Consume the EndOfStatement.
3629 bool MipsAsmParser::parseSetFpDirective() {
3630 MCAsmParser &Parser = getParser();
3631 MipsABIFlagsSection::FpABIKind FpAbiVal;
3632 // Line can be: .set fp=32
3635 Parser.Lex(); // Eat fp token
3636 AsmToken Tok = Parser.getTok();
3637 if (Tok.isNot(AsmToken::Equal)) {
3638 reportParseError("unexpected token, expected equals sign '='");
3641 Parser.Lex(); // Eat '=' token.
3642 Tok = Parser.getTok();
3644 if (!parseFpABIValue(FpAbiVal, ".set"))
3647 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3648 reportParseError("unexpected token, expected end of statement");
3651 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3652 Parser.Lex(); // Consume the EndOfStatement.
3656 bool MipsAsmParser::parseSetPopDirective() {
3657 MCAsmParser &Parser = getParser();
3658 SMLoc Loc = getLexer().getLoc();
3661 if (getLexer().isNot(AsmToken::EndOfStatement))
3662 return reportParseError("unexpected token, expected end of statement");
3664 // Always keep an element on the options "stack" to prevent the user
3665 // from changing the initial options. This is how we remember them.
3666 if (AssemblerOptions.size() == 2)
3667 return reportParseError(Loc, ".set pop with no .set push");
3669 AssemblerOptions.pop_back();
3670 setAvailableFeatures(
3671 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
3672 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
3674 getTargetStreamer().emitDirectiveSetPop();
3678 bool MipsAsmParser::parseSetPushDirective() {
3679 MCAsmParser &Parser = getParser();
3681 if (getLexer().isNot(AsmToken::EndOfStatement))
3682 return reportParseError("unexpected token, expected end of statement");
3684 // Create a copy of the current assembler options environment and push it.
3685 AssemblerOptions.push_back(
3686 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3688 getTargetStreamer().emitDirectiveSetPush();
3692 bool MipsAsmParser::parseSetSoftFloatDirective() {
3693 MCAsmParser &Parser = getParser();
3695 if (getLexer().isNot(AsmToken::EndOfStatement))
3696 return reportParseError("unexpected token, expected end of statement");
3698 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3699 getTargetStreamer().emitDirectiveSetSoftFloat();
3703 bool MipsAsmParser::parseSetHardFloatDirective() {
3704 MCAsmParser &Parser = getParser();
3706 if (getLexer().isNot(AsmToken::EndOfStatement))
3707 return reportParseError("unexpected token, expected end of statement");
3709 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3710 getTargetStreamer().emitDirectiveSetHardFloat();
3714 bool MipsAsmParser::parseSetAssignment() {
3716 const MCExpr *Value;
3717 MCAsmParser &Parser = getParser();
3719 if (Parser.parseIdentifier(Name))
3720 reportParseError("expected identifier after .set");
3722 if (getLexer().isNot(AsmToken::Comma))
3723 return reportParseError("unexpected token, expected comma");
3726 if (Parser.parseExpression(Value))
3727 return reportParseError("expected valid expression after comma");
3729 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3730 Sym->setVariableValue(Value);
3735 bool MipsAsmParser::parseSetMips0Directive() {
3736 MCAsmParser &Parser = getParser();
3738 if (getLexer().isNot(AsmToken::EndOfStatement))
3739 return reportParseError("unexpected token, expected end of statement");
3741 // Reset assembler options to their initial values.
3742 setAvailableFeatures(
3743 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
3744 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
3745 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3747 getTargetStreamer().emitDirectiveSetMips0();
3751 bool MipsAsmParser::parseSetArchDirective() {
3752 MCAsmParser &Parser = getParser();
3754 if (getLexer().isNot(AsmToken::Equal))
3755 return reportParseError("unexpected token, expected equals sign");
3759 if (Parser.parseIdentifier(Arch))
3760 return reportParseError("expected arch identifier");
3762 StringRef ArchFeatureName =
3763 StringSwitch<StringRef>(Arch)
3764 .Case("mips1", "mips1")
3765 .Case("mips2", "mips2")
3766 .Case("mips3", "mips3")
3767 .Case("mips4", "mips4")
3768 .Case("mips5", "mips5")
3769 .Case("mips32", "mips32")
3770 .Case("mips32r2", "mips32r2")
3771 .Case("mips32r3", "mips32r3")
3772 .Case("mips32r5", "mips32r5")
3773 .Case("mips32r6", "mips32r6")
3774 .Case("mips64", "mips64")
3775 .Case("mips64r2", "mips64r2")
3776 .Case("mips64r3", "mips64r3")
3777 .Case("mips64r5", "mips64r5")
3778 .Case("mips64r6", "mips64r6")
3779 .Case("cnmips", "cnmips")
3780 .Case("r4000", "mips3") // This is an implementation of Mips3.
3783 if (ArchFeatureName.empty())
3784 return reportParseError("unsupported architecture");
3786 selectArch(ArchFeatureName);
3787 getTargetStreamer().emitDirectiveSetArch(Arch);
3791 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3792 MCAsmParser &Parser = getParser();
3794 if (getLexer().isNot(AsmToken::EndOfStatement))
3795 return reportParseError("unexpected token, expected end of statement");
3799 llvm_unreachable("Unimplemented feature");
3800 case Mips::FeatureDSP:
3801 setFeatureBits(Mips::FeatureDSP, "dsp");
3802 getTargetStreamer().emitDirectiveSetDsp();
3804 case Mips::FeatureMicroMips:
3805 getTargetStreamer().emitDirectiveSetMicroMips();
3807 case Mips::FeatureMips1:
3808 selectArch("mips1");
3809 getTargetStreamer().emitDirectiveSetMips1();
3811 case Mips::FeatureMips2:
3812 selectArch("mips2");
3813 getTargetStreamer().emitDirectiveSetMips2();
3815 case Mips::FeatureMips3:
3816 selectArch("mips3");
3817 getTargetStreamer().emitDirectiveSetMips3();
3819 case Mips::FeatureMips4:
3820 selectArch("mips4");
3821 getTargetStreamer().emitDirectiveSetMips4();
3823 case Mips::FeatureMips5:
3824 selectArch("mips5");
3825 getTargetStreamer().emitDirectiveSetMips5();
3827 case Mips::FeatureMips32:
3828 selectArch("mips32");
3829 getTargetStreamer().emitDirectiveSetMips32();
3831 case Mips::FeatureMips32r2:
3832 selectArch("mips32r2");
3833 getTargetStreamer().emitDirectiveSetMips32R2();
3835 case Mips::FeatureMips32r3:
3836 selectArch("mips32r3");
3837 getTargetStreamer().emitDirectiveSetMips32R3();
3839 case Mips::FeatureMips32r5:
3840 selectArch("mips32r5");
3841 getTargetStreamer().emitDirectiveSetMips32R5();
3843 case Mips::FeatureMips32r6:
3844 selectArch("mips32r6");
3845 getTargetStreamer().emitDirectiveSetMips32R6();
3847 case Mips::FeatureMips64:
3848 selectArch("mips64");
3849 getTargetStreamer().emitDirectiveSetMips64();
3851 case Mips::FeatureMips64r2:
3852 selectArch("mips64r2");
3853 getTargetStreamer().emitDirectiveSetMips64R2();
3855 case Mips::FeatureMips64r3:
3856 selectArch("mips64r3");
3857 getTargetStreamer().emitDirectiveSetMips64R3();
3859 case Mips::FeatureMips64r5:
3860 selectArch("mips64r5");
3861 getTargetStreamer().emitDirectiveSetMips64R5();
3863 case Mips::FeatureMips64r6:
3864 selectArch("mips64r6");
3865 getTargetStreamer().emitDirectiveSetMips64R6();
3871 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3872 MCAsmParser &Parser = getParser();
3873 if (getLexer().isNot(AsmToken::Comma)) {
3874 SMLoc Loc = getLexer().getLoc();
3875 Parser.eatToEndOfStatement();
3876 return Error(Loc, ErrorStr);
3879 Parser.Lex(); // Eat the comma.
3883 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3884 if (AssemblerOptions.back()->isReorder())
3885 Warning(Loc, ".cpload should be inside a noreorder section");
3887 if (inMips16Mode()) {
3888 reportParseError(".cpload is not supported in Mips16 mode");
3892 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3893 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3894 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3895 reportParseError("expected register containing function address");
3899 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3900 if (!RegOpnd.isGPRAsmReg()) {
3901 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3905 // If this is not the end of the statement, report an error.
3906 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3907 reportParseError("unexpected token, expected end of statement");
3911 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3915 bool MipsAsmParser::parseDirectiveCPSetup() {
3916 MCAsmParser &Parser = getParser();
3919 bool SaveIsReg = true;
3921 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3922 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3923 if (ResTy == MatchOperand_NoMatch) {
3924 reportParseError("expected register containing function address");
3925 Parser.eatToEndOfStatement();
3929 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3930 if (!FuncRegOpnd.isGPRAsmReg()) {
3931 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3932 Parser.eatToEndOfStatement();
3936 FuncReg = FuncRegOpnd.getGPR32Reg();
3939 if (!eatComma("unexpected token, expected comma"))
3942 ResTy = parseAnyRegister(TmpReg);
3943 if (ResTy == MatchOperand_NoMatch) {
3944 const AsmToken &Tok = Parser.getTok();
3945 if (Tok.is(AsmToken::Integer)) {
3946 Save = Tok.getIntVal();
3950 reportParseError("expected save register or stack offset");
3951 Parser.eatToEndOfStatement();
3955 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3956 if (!SaveOpnd.isGPRAsmReg()) {
3957 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3958 Parser.eatToEndOfStatement();
3961 Save = SaveOpnd.getGPR32Reg();
3964 if (!eatComma("unexpected token, expected comma"))
3968 if (Parser.parseExpression(Expr)) {
3969 reportParseError("expected expression");
3973 if (Expr->getKind() != MCExpr::SymbolRef) {
3974 reportParseError("expected symbol");
3977 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3979 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3984 bool MipsAsmParser::parseDirectiveNaN() {
3985 MCAsmParser &Parser = getParser();
3986 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3987 const AsmToken &Tok = Parser.getTok();
3989 if (Tok.getString() == "2008") {
3991 getTargetStreamer().emitDirectiveNaN2008();
3993 } else if (Tok.getString() == "legacy") {
3995 getTargetStreamer().emitDirectiveNaNLegacy();
3999 // If we don't recognize the option passed to the .nan
4000 // directive (e.g. no option or unknown option), emit an error.
4001 reportParseError("invalid option in .nan directive");
4005 bool MipsAsmParser::parseDirectiveSet() {
4006 MCAsmParser &Parser = getParser();
4007 // Get the next token.
4008 const AsmToken &Tok = Parser.getTok();
4010 if (Tok.getString() == "noat") {
4011 return parseSetNoAtDirective();
4012 } else if (Tok.getString() == "at") {
4013 return parseSetAtDirective();
4014 } else if (Tok.getString() == "arch") {
4015 return parseSetArchDirective();
4016 } else if (Tok.getString() == "fp") {
4017 return parseSetFpDirective();
4018 } else if (Tok.getString() == "pop") {
4019 return parseSetPopDirective();
4020 } else if (Tok.getString() == "push") {
4021 return parseSetPushDirective();
4022 } else if (Tok.getString() == "reorder") {
4023 return parseSetReorderDirective();
4024 } else if (Tok.getString() == "noreorder") {
4025 return parseSetNoReorderDirective();
4026 } else if (Tok.getString() == "macro") {
4027 return parseSetMacroDirective();
4028 } else if (Tok.getString() == "nomacro") {
4029 return parseSetNoMacroDirective();
4030 } else if (Tok.getString() == "mips16") {
4031 return parseSetMips16Directive();
4032 } else if (Tok.getString() == "nomips16") {
4033 return parseSetNoMips16Directive();
4034 } else if (Tok.getString() == "nomicromips") {
4035 getTargetStreamer().emitDirectiveSetNoMicroMips();
4036 Parser.eatToEndOfStatement();
4038 } else if (Tok.getString() == "micromips") {
4039 return parseSetFeature(Mips::FeatureMicroMips);
4040 } else if (Tok.getString() == "mips0") {
4041 return parseSetMips0Directive();
4042 } else if (Tok.getString() == "mips1") {
4043 return parseSetFeature(Mips::FeatureMips1);
4044 } else if (Tok.getString() == "mips2") {
4045 return parseSetFeature(Mips::FeatureMips2);
4046 } else if (Tok.getString() == "mips3") {
4047 return parseSetFeature(Mips::FeatureMips3);
4048 } else if (Tok.getString() == "mips4") {
4049 return parseSetFeature(Mips::FeatureMips4);
4050 } else if (Tok.getString() == "mips5") {
4051 return parseSetFeature(Mips::FeatureMips5);
4052 } else if (Tok.getString() == "mips32") {
4053 return parseSetFeature(Mips::FeatureMips32);
4054 } else if (Tok.getString() == "mips32r2") {
4055 return parseSetFeature(Mips::FeatureMips32r2);
4056 } else if (Tok.getString() == "mips32r3") {
4057 return parseSetFeature(Mips::FeatureMips32r3);
4058 } else if (Tok.getString() == "mips32r5") {
4059 return parseSetFeature(Mips::FeatureMips32r5);
4060 } else if (Tok.getString() == "mips32r6") {
4061 return parseSetFeature(Mips::FeatureMips32r6);
4062 } else if (Tok.getString() == "mips64") {
4063 return parseSetFeature(Mips::FeatureMips64);
4064 } else if (Tok.getString() == "mips64r2") {
4065 return parseSetFeature(Mips::FeatureMips64r2);
4066 } else if (Tok.getString() == "mips64r3") {
4067 return parseSetFeature(Mips::FeatureMips64r3);
4068 } else if (Tok.getString() == "mips64r5") {
4069 return parseSetFeature(Mips::FeatureMips64r5);
4070 } else if (Tok.getString() == "mips64r6") {
4071 return parseSetFeature(Mips::FeatureMips64r6);
4072 } else if (Tok.getString() == "dsp") {
4073 return parseSetFeature(Mips::FeatureDSP);
4074 } else if (Tok.getString() == "nodsp") {
4075 return parseSetNoDspDirective();
4076 } else if (Tok.getString() == "msa") {
4077 return parseSetMsaDirective();
4078 } else if (Tok.getString() == "nomsa") {
4079 return parseSetNoMsaDirective();
4080 } else if (Tok.getString() == "softfloat") {
4081 return parseSetSoftFloatDirective();
4082 } else if (Tok.getString() == "hardfloat") {
4083 return parseSetHardFloatDirective();
4085 // It is just an identifier, look for an assignment.
4086 parseSetAssignment();
4093 /// parseDataDirective
4094 /// ::= .word [ expression (, expression)* ]
4095 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4096 MCAsmParser &Parser = getParser();
4097 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4099 const MCExpr *Value;
4100 if (getParser().parseExpression(Value))
4103 getParser().getStreamer().EmitValue(Value, Size);
4105 if (getLexer().is(AsmToken::EndOfStatement))
4108 if (getLexer().isNot(AsmToken::Comma))
4109 return Error(L, "unexpected token, expected comma");
4118 /// parseDirectiveGpWord
4119 /// ::= .gpword local_sym
4120 bool MipsAsmParser::parseDirectiveGpWord() {
4121 MCAsmParser &Parser = getParser();
4122 const MCExpr *Value;
4123 // EmitGPRel32Value requires an expression, so we are using base class
4124 // method to evaluate the expression.
4125 if (getParser().parseExpression(Value))
4127 getParser().getStreamer().EmitGPRel32Value(Value);
4129 if (getLexer().isNot(AsmToken::EndOfStatement))
4130 return Error(getLexer().getLoc(),
4131 "unexpected token, expected end of statement");
4132 Parser.Lex(); // Eat EndOfStatement token.
4136 /// parseDirectiveGpDWord
4137 /// ::= .gpdword local_sym
4138 bool MipsAsmParser::parseDirectiveGpDWord() {
4139 MCAsmParser &Parser = getParser();
4140 const MCExpr *Value;
4141 // EmitGPRel64Value requires an expression, so we are using base class
4142 // method to evaluate the expression.
4143 if (getParser().parseExpression(Value))
4145 getParser().getStreamer().EmitGPRel64Value(Value);
4147 if (getLexer().isNot(AsmToken::EndOfStatement))
4148 return Error(getLexer().getLoc(),
4149 "unexpected token, expected end of statement");
4150 Parser.Lex(); // Eat EndOfStatement token.
4154 bool MipsAsmParser::parseDirectiveOption() {
4155 MCAsmParser &Parser = getParser();
4156 // Get the option token.
4157 AsmToken Tok = Parser.getTok();
4158 // At the moment only identifiers are supported.
4159 if (Tok.isNot(AsmToken::Identifier)) {
4160 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4161 Parser.eatToEndOfStatement();
4165 StringRef Option = Tok.getIdentifier();
4167 if (Option == "pic0") {
4168 getTargetStreamer().emitDirectiveOptionPic0();
4170 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4171 Error(Parser.getTok().getLoc(),
4172 "unexpected token, expected end of statement");
4173 Parser.eatToEndOfStatement();
4178 if (Option == "pic2") {
4179 getTargetStreamer().emitDirectiveOptionPic2();
4181 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4182 Error(Parser.getTok().getLoc(),
4183 "unexpected token, expected end of statement");
4184 Parser.eatToEndOfStatement();
4190 Warning(Parser.getTok().getLoc(),
4191 "unknown option, expected 'pic0' or 'pic2'");
4192 Parser.eatToEndOfStatement();
4196 /// parseInsnDirective
4198 bool MipsAsmParser::parseInsnDirective() {
4199 // If this is not the end of the statement, report an error.
4200 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4201 reportParseError("unexpected token, expected end of statement");
4205 // The actual label marking happens in
4206 // MipsELFStreamer::createPendingLabelRelocs().
4207 getTargetStreamer().emitDirectiveInsn();
4209 getParser().Lex(); // Eat EndOfStatement token.
4213 /// parseDirectiveModule
4214 /// ::= .module oddspreg
4215 /// ::= .module nooddspreg
4216 /// ::= .module fp=value
4217 bool MipsAsmParser::parseDirectiveModule() {
4218 MCAsmParser &Parser = getParser();
4219 MCAsmLexer &Lexer = getLexer();
4220 SMLoc L = Lexer.getLoc();
4222 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4223 // TODO : get a better message.
4224 reportParseError(".module directive must appear before any code");
4229 if (Parser.parseIdentifier(Option)) {
4230 reportParseError("expected .module option identifier");
4234 if (Option == "oddspreg") {
4235 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4236 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4238 // If this is not the end of the statement, report an error.
4239 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4240 reportParseError("unexpected token, expected end of statement");
4244 return false; // parseDirectiveModule has finished successfully.
4245 } else if (Option == "nooddspreg") {
4247 Error(L, "'.module nooddspreg' requires the O32 ABI");
4251 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4252 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4254 // If this is not the end of the statement, report an error.
4255 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4256 reportParseError("unexpected token, expected end of statement");
4260 return false; // parseDirectiveModule has finished successfully.
4261 } else if (Option == "fp") {
4262 return parseDirectiveModuleFP();
4264 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4268 /// parseDirectiveModuleFP
4272 bool MipsAsmParser::parseDirectiveModuleFP() {
4273 MCAsmParser &Parser = getParser();
4274 MCAsmLexer &Lexer = getLexer();
4276 if (Lexer.isNot(AsmToken::Equal)) {
4277 reportParseError("unexpected token, expected equals sign '='");
4280 Parser.Lex(); // Eat '=' token.
4282 MipsABIFlagsSection::FpABIKind FpABI;
4283 if (!parseFpABIValue(FpABI, ".module"))
4286 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4287 reportParseError("unexpected token, expected end of statement");
4291 // Emit appropriate flags.
4292 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4293 Parser.Lex(); // Consume the EndOfStatement.
4297 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4298 StringRef Directive) {
4299 MCAsmParser &Parser = getParser();
4300 MCAsmLexer &Lexer = getLexer();
4302 if (Lexer.is(AsmToken::Identifier)) {
4303 StringRef Value = Parser.getTok().getString();
4306 if (Value != "xx") {
4307 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4312 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4316 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4320 if (Lexer.is(AsmToken::Integer)) {
4321 unsigned Value = Parser.getTok().getIntVal();
4324 if (Value != 32 && Value != 64) {
4325 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4331 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4335 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4337 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4345 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4346 MCAsmParser &Parser = getParser();
4347 StringRef IDVal = DirectiveID.getString();
4349 if (IDVal == ".cpload")
4350 return parseDirectiveCpLoad(DirectiveID.getLoc());
4351 if (IDVal == ".dword") {
4352 parseDataDirective(8, DirectiveID.getLoc());
4355 if (IDVal == ".ent") {
4356 StringRef SymbolName;
4358 if (Parser.parseIdentifier(SymbolName)) {
4359 reportParseError("expected identifier after .ent");
4363 // There's an undocumented extension that allows an integer to
4364 // follow the name of the procedure which AFAICS is ignored by GAS.
4365 // Example: .ent foo,2
4366 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4367 if (getLexer().isNot(AsmToken::Comma)) {
4368 // Even though we accept this undocumented extension for compatibility
4369 // reasons, the additional integer argument does not actually change
4370 // the behaviour of the '.ent' directive, so we would like to discourage
4371 // its use. We do this by not referring to the extended version in
4372 // error messages which are not directly related to its use.
4373 reportParseError("unexpected token, expected end of statement");
4376 Parser.Lex(); // Eat the comma.
4377 const MCExpr *DummyNumber;
4378 int64_t DummyNumberVal;
4379 // If the user was explicitly trying to use the extended version,
4380 // we still give helpful extension-related error messages.
4381 if (Parser.parseExpression(DummyNumber)) {
4382 reportParseError("expected number after comma");
4385 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4386 reportParseError("expected an absolute expression after comma");
4391 // If this is not the end of the statement, report an error.
4392 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4393 reportParseError("unexpected token, expected end of statement");
4397 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4399 getTargetStreamer().emitDirectiveEnt(*Sym);
4404 if (IDVal == ".end") {
4405 StringRef SymbolName;
4407 if (Parser.parseIdentifier(SymbolName)) {
4408 reportParseError("expected identifier after .end");
4412 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4413 reportParseError("unexpected token, expected end of statement");
4417 if (CurrentFn == nullptr) {
4418 reportParseError(".end used without .ent");
4422 if ((SymbolName != CurrentFn->getName())) {
4423 reportParseError(".end symbol does not match .ent symbol");
4427 getTargetStreamer().emitDirectiveEnd(SymbolName);
4428 CurrentFn = nullptr;
4432 if (IDVal == ".frame") {
4433 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4434 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4435 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4436 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4437 reportParseError("expected stack register");
4441 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4442 if (!StackRegOpnd.isGPRAsmReg()) {
4443 reportParseError(StackRegOpnd.getStartLoc(),
4444 "expected general purpose register");
4447 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4449 if (Parser.getTok().is(AsmToken::Comma))
4452 reportParseError("unexpected token, expected comma");
4456 // Parse the frame size.
4457 const MCExpr *FrameSize;
4458 int64_t FrameSizeVal;
4460 if (Parser.parseExpression(FrameSize)) {
4461 reportParseError("expected frame size value");
4465 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4466 reportParseError("frame size not an absolute expression");
4470 if (Parser.getTok().is(AsmToken::Comma))
4473 reportParseError("unexpected token, expected comma");
4477 // Parse the return register.
4479 ResTy = parseAnyRegister(TmpReg);
4480 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4481 reportParseError("expected return register");
4485 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4486 if (!ReturnRegOpnd.isGPRAsmReg()) {
4487 reportParseError(ReturnRegOpnd.getStartLoc(),
4488 "expected general purpose register");
4492 // If this is not the end of the statement, report an error.
4493 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4494 reportParseError("unexpected token, expected end of statement");
4498 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4499 ReturnRegOpnd.getGPR32Reg());
4503 if (IDVal == ".set") {
4504 return parseDirectiveSet();
4507 if (IDVal == ".mask" || IDVal == ".fmask") {
4508 // .mask bitmask, frame_offset
4509 // bitmask: One bit for each register used.
4510 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4511 // first register is expected to be saved.
4513 // .mask 0x80000000, -4
4514 // .fmask 0x80000000, -4
4517 // Parse the bitmask
4518 const MCExpr *BitMask;
4521 if (Parser.parseExpression(BitMask)) {
4522 reportParseError("expected bitmask value");
4526 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4527 reportParseError("bitmask not an absolute expression");
4531 if (Parser.getTok().is(AsmToken::Comma))
4534 reportParseError("unexpected token, expected comma");
4538 // Parse the frame_offset
4539 const MCExpr *FrameOffset;
4540 int64_t FrameOffsetVal;
4542 if (Parser.parseExpression(FrameOffset)) {
4543 reportParseError("expected frame offset value");
4547 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4548 reportParseError("frame offset not an absolute expression");
4552 // If this is not the end of the statement, report an error.
4553 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4554 reportParseError("unexpected token, expected end of statement");
4558 if (IDVal == ".mask")
4559 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4561 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4565 if (IDVal == ".nan")
4566 return parseDirectiveNaN();
4568 if (IDVal == ".gpword") {
4569 parseDirectiveGpWord();
4573 if (IDVal == ".gpdword") {
4574 parseDirectiveGpDWord();
4578 if (IDVal == ".word") {
4579 parseDataDirective(4, DirectiveID.getLoc());
4583 if (IDVal == ".option")
4584 return parseDirectiveOption();
4586 if (IDVal == ".abicalls") {
4587 getTargetStreamer().emitDirectiveAbiCalls();
4588 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4589 Error(Parser.getTok().getLoc(),
4590 "unexpected token, expected end of statement");
4592 Parser.eatToEndOfStatement();
4597 if (IDVal == ".cpsetup")
4598 return parseDirectiveCPSetup();
4600 if (IDVal == ".module")
4601 return parseDirectiveModule();
4603 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4604 return parseInternalDirectiveReallowModule();
4606 if (IDVal == ".insn")
4607 return parseInsnDirective();
4612 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4613 // If this is not the end of the statement, report an error.
4614 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4615 reportParseError("unexpected token, expected end of statement");
4619 getTargetStreamer().reallowModuleDirective();
4621 getParser().Lex(); // Eat EndOfStatement token.
4625 extern "C" void LLVMInitializeMipsAsmParser() {
4626 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4627 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4628 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4629 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4632 #define GET_REGISTER_MATCHER
4633 #define GET_MATCHER_IMPLEMENTATION
4634 #include "MipsGenAsmMatcher.inc"