1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(const FeatureBitset &Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegIndex();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegIndex() const { return ATReg; }
57 bool setATRegIndex(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 const FeatureBitset &getFeatures() const { return Features; }
74 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const FeatureBitset AllArchRelatedMask;
87 FeatureBitset Features;
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103 class MipsAsmParser : public MCTargetAsmParser {
104 MipsTargetStreamer &getTargetStreamer() {
105 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
106 return static_cast<MipsTargetStreamer &>(TS);
109 MCSubtargetInfo &STI;
111 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
112 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113 // nullptr, which indicates that no function is currently
114 // selected. This usually happens after an '.end func'
117 // Print a warning along with its fix-it message at the given range.
118 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
119 SMRange Range, bool ShowColors = true);
121 #define GET_ASSEMBLER_HEADER
122 #include "MipsGenAsmMatcher.inc"
124 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
126 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
127 OperandVector &Operands, MCStreamer &Out,
129 bool MatchingInlineAsm) override;
131 /// Parse a register as used in CFI directives
132 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
134 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
136 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
138 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
139 SMLoc NameLoc, OperandVector &Operands) override;
141 bool ParseDirective(AsmToken DirectiveID) override;
143 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy
146 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
147 StringRef Identifier, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy
150 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
152 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
154 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
156 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
158 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
160 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseRegisterPair (OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseMovePRegPair(OperandVector &Operands);
168 MipsAsmParser::OperandMatchResultTy
169 parseRegisterList (OperandVector &Operands);
171 bool searchSymbolAlias(OperandVector &Operands);
173 bool parseOperand(OperandVector &, StringRef Mnemonic);
175 bool needsExpansion(MCInst &Inst);
177 // Expands assembly pseudo instructions.
178 // Returns false on success, true otherwise.
179 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
186 bool Is32BitImm, SMLoc IDLoc,
187 SmallVectorImpl<MCInst> &Instructions);
189 bool loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
190 bool Is32BitSym, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions);
199 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
200 SmallVectorImpl<MCInst> &Instructions);
201 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions);
204 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
205 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
208 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
215 SmallVectorImpl<MCInst> &Instructions);
217 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
218 SmallVectorImpl<MCInst> &Instructions);
220 bool reportParseError(Twine ErrorMsg);
221 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
223 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
224 bool parseRelocOperand(const MCExpr *&Res);
226 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
228 bool isEvaluated(const MCExpr *Expr);
229 bool parseSetMips0Directive();
230 bool parseSetArchDirective();
231 bool parseSetFeature(uint64_t Feature);
232 bool parseDirectiveCpLoad(SMLoc Loc);
233 bool parseDirectiveCPSetup();
234 bool parseDirectiveNaN();
235 bool parseDirectiveSet();
236 bool parseDirectiveOption();
237 bool parseInsnDirective();
239 bool parseSetAtDirective();
240 bool parseSetNoAtDirective();
241 bool parseSetMacroDirective();
242 bool parseSetNoMacroDirective();
243 bool parseSetMsaDirective();
244 bool parseSetNoMsaDirective();
245 bool parseSetNoDspDirective();
246 bool parseSetReorderDirective();
247 bool parseSetNoReorderDirective();
248 bool parseSetMips16Directive();
249 bool parseSetNoMips16Directive();
250 bool parseSetFpDirective();
251 bool parseSetPopDirective();
252 bool parseSetPushDirective();
253 bool parseSetSoftFloatDirective();
254 bool parseSetHardFloatDirective();
256 bool parseSetAssignment();
258 bool parseDataDirective(unsigned Size, SMLoc L);
259 bool parseDirectiveGpWord();
260 bool parseDirectiveGpDWord();
261 bool parseDirectiveModule();
262 bool parseDirectiveModuleFP();
263 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
264 StringRef Directive);
266 bool parseInternalDirectiveReallowModule();
268 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
270 bool eatComma(StringRef ErrorStr);
272 int matchCPURegisterName(StringRef Symbol);
274 int matchHWRegsRegisterName(StringRef Symbol);
276 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
278 int matchFPURegisterName(StringRef Name);
280 int matchFCCRegisterName(StringRef Name);
282 int matchACRegisterName(StringRef Name);
284 int matchMSA128RegisterName(StringRef Name);
286 int matchMSA128CtrlRegisterName(StringRef Name);
288 unsigned getReg(int RC, int RegNo);
290 unsigned getGPR(int RegNo);
292 /// Returns the internal register number for the current AT. Also checks if
293 /// the current AT is unavailable (set to $0) and gives an error if it is.
294 /// This should be used in pseudo-instruction expansions which need AT.
295 unsigned getATReg(SMLoc Loc);
297 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
298 SmallVectorImpl<MCInst> &Instructions);
300 // Helper function that checks if the value of a vector index is within the
301 // boundaries of accepted values for each RegisterKind
302 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
303 bool validateMSAIndex(int Val, int RegKind);
305 // Selects a new architecture by updating the FeatureBits with the necessary
306 // info including implied dependencies.
307 // Internally, it clears all the feature bits related to *any* architecture
308 // and selects the new one using the ToggleFeature functionality of the
309 // MCSubtargetInfo object that handles implied dependencies. The reason we
310 // clear all the arch related bits manually is because ToggleFeature only
311 // clears the features that imply the feature being cleared and not the
312 // features implied by the feature being cleared. This is easier to see
314 // --------------------------------------------------
315 // | Feature | Implies |
316 // | -------------------------------------------------|
317 // | FeatureMips1 | None |
318 // | FeatureMips2 | FeatureMips1 |
319 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
320 // | FeatureMips4 | FeatureMips3 |
322 // --------------------------------------------------
324 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
325 // FeatureMipsGP64 | FeatureMips1)
326 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
327 void selectArch(StringRef ArchFeature) {
328 FeatureBitset FeatureBits = STI.getFeatureBits();
329 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
330 STI.setFeatureBits(FeatureBits);
331 setAvailableFeatures(
332 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
333 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
336 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
337 if (!(STI.getFeatureBits()[Feature])) {
338 setAvailableFeatures(
339 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
340 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
344 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
345 if (STI.getFeatureBits()[Feature]) {
346 setAvailableFeatures(
347 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
348 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
353 enum MipsMatchResultTy {
354 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
355 #define GET_OPERAND_DIAGNOSTIC_TYPES
356 #include "MipsGenAsmMatcher.inc"
357 #undef GET_OPERAND_DIAGNOSTIC_TYPES
361 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
362 const MCInstrInfo &MII, const MCTargetOptions &Options)
363 : MCTargetAsmParser(), STI(sti),
364 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
365 sti.getCPU(), Options)) {
366 MCAsmParserExtension::Initialize(parser);
368 parser.addAliasForDirective(".asciiz", ".asciz");
370 // Initialize the set of available features.
371 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
373 // Remember the initial assembler options. The user can not modify these.
374 AssemblerOptions.push_back(
375 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
377 // Create an assembler options environment for the user to modify.
378 AssemblerOptions.push_back(
379 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
381 getTargetStreamer().updateABIInfo(*this);
383 if (!isABI_O32() && !useOddSPReg() != 0)
384 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
389 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
390 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
392 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
393 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
394 const MipsABIInfo &getABI() const { return ABI; }
395 bool isABI_N32() const { return ABI.IsN32(); }
396 bool isABI_N64() const { return ABI.IsN64(); }
397 bool isABI_O32() const { return ABI.IsO32(); }
398 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
400 bool useOddSPReg() const {
401 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
404 bool inMicroMipsMode() const {
405 return STI.getFeatureBits()[Mips::FeatureMicroMips];
407 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
408 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
409 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
410 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
411 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
412 bool hasMips32() const {
413 return STI.getFeatureBits()[Mips::FeatureMips32];
415 bool hasMips64() const {
416 return STI.getFeatureBits()[Mips::FeatureMips64];
418 bool hasMips32r2() const {
419 return STI.getFeatureBits()[Mips::FeatureMips32r2];
421 bool hasMips64r2() const {
422 return STI.getFeatureBits()[Mips::FeatureMips64r2];
424 bool hasMips32r3() const {
425 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
427 bool hasMips64r3() const {
428 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
430 bool hasMips32r5() const {
431 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
433 bool hasMips64r5() const {
434 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
436 bool hasMips32r6() const {
437 return STI.getFeatureBits()[Mips::FeatureMips32r6];
439 bool hasMips64r6() const {
440 return STI.getFeatureBits()[Mips::FeatureMips64r6];
443 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
444 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
445 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
446 bool hasCnMips() const {
447 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
450 bool inMips16Mode() const {
451 return STI.getFeatureBits()[Mips::FeatureMips16];
454 bool useSoftFloat() const {
455 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
458 /// Warn if RegIndex is the same as the current AT.
459 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
461 void warnIfNoMacro(SMLoc Loc);
467 /// MipsOperand - Instances of this class represent a parsed Mips machine
469 class MipsOperand : public MCParsedAsmOperand {
471 /// Broad categories of register classes
472 /// The exact class is finalized by the render method.
474 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
475 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
477 RegKind_FCC = 4, /// FCC
478 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
479 RegKind_MSACtrl = 16, /// MSA control registers
480 RegKind_COP2 = 32, /// COP2
481 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
483 RegKind_CCR = 128, /// CCR
484 RegKind_HWRegs = 256, /// HWRegs
485 RegKind_COP3 = 512, /// COP3
487 /// Potentially any (e.g. $1)
488 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
489 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
490 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
495 k_Immediate, /// An immediate (possibly involving symbol references)
496 k_Memory, /// Base + Offset Memory Address
497 k_PhysRegister, /// A physical register from the Mips namespace
498 k_RegisterIndex, /// A register index in one or more RegKind.
499 k_Token, /// A simple token
500 k_RegList, /// A physical register list
501 k_RegPair /// A pair of physical register
505 MipsOperand(KindTy K, MipsAsmParser &Parser)
506 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
509 /// For diagnostics, and checking the assembler temporary
510 MipsAsmParser &AsmParser;
518 unsigned Num; /// Register Number
522 unsigned Index; /// Index into the register class
523 RegKind Kind; /// Bitfield of the kinds it could possibly be
524 const MCRegisterInfo *RegInfo;
537 SmallVector<unsigned, 10> *List;
542 struct PhysRegOp PhysReg;
543 struct RegIdxOp RegIdx;
546 struct RegListOp RegList;
549 SMLoc StartLoc, EndLoc;
551 /// Internal constructor for register kinds
552 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
553 const MCRegisterInfo *RegInfo,
555 MipsAsmParser &Parser) {
556 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
557 Op->RegIdx.Index = Index;
558 Op->RegIdx.RegInfo = RegInfo;
559 Op->RegIdx.Kind = RegKind;
566 /// Coerce the register to GPR32 and return the real register for the current
568 unsigned getGPR32Reg() const {
569 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
570 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
571 unsigned ClassID = Mips::GPR32RegClassID;
572 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
575 /// Coerce the register to GPR32 and return the real register for the current
577 unsigned getGPRMM16Reg() const {
578 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
579 unsigned ClassID = Mips::GPR32RegClassID;
580 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
583 /// Coerce the register to GPR64 and return the real register for the current
585 unsigned getGPR64Reg() const {
586 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
587 unsigned ClassID = Mips::GPR64RegClassID;
588 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
592 /// Coerce the register to AFGR64 and return the real register for the current
594 unsigned getAFGR64Reg() const {
595 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
596 if (RegIdx.Index % 2 != 0)
597 AsmParser.Warning(StartLoc, "Float register should be even.");
598 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
599 .getRegister(RegIdx.Index / 2);
602 /// Coerce the register to FGR64 and return the real register for the current
604 unsigned getFGR64Reg() const {
605 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
606 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
607 .getRegister(RegIdx.Index);
610 /// Coerce the register to FGR32 and return the real register for the current
612 unsigned getFGR32Reg() const {
613 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
614 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
615 .getRegister(RegIdx.Index);
618 /// Coerce the register to FGRH32 and return the real register for the current
620 unsigned getFGRH32Reg() const {
621 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
622 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
623 .getRegister(RegIdx.Index);
626 /// Coerce the register to FCC and return the real register for the current
628 unsigned getFCCReg() const {
629 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
630 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
631 .getRegister(RegIdx.Index);
634 /// Coerce the register to MSA128 and return the real register for the current
636 unsigned getMSA128Reg() const {
637 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
638 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
640 unsigned ClassID = Mips::MSA128BRegClassID;
641 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
644 /// Coerce the register to MSACtrl and return the real register for the
646 unsigned getMSACtrlReg() const {
647 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
648 unsigned ClassID = Mips::MSACtrlRegClassID;
649 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
652 /// Coerce the register to COP2 and return the real register for the
654 unsigned getCOP2Reg() const {
655 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
656 unsigned ClassID = Mips::COP2RegClassID;
657 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
660 /// Coerce the register to COP3 and return the real register for the
662 unsigned getCOP3Reg() const {
663 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
664 unsigned ClassID = Mips::COP3RegClassID;
665 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
668 /// Coerce the register to ACC64DSP and return the real register for the
670 unsigned getACC64DSPReg() const {
671 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
672 unsigned ClassID = Mips::ACC64DSPRegClassID;
673 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
676 /// Coerce the register to HI32DSP and return the real register for the
678 unsigned getHI32DSPReg() const {
679 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
680 unsigned ClassID = Mips::HI32DSPRegClassID;
681 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
684 /// Coerce the register to LO32DSP and return the real register for the
686 unsigned getLO32DSPReg() const {
687 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
688 unsigned ClassID = Mips::LO32DSPRegClassID;
689 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
692 /// Coerce the register to CCR and return the real register for the
694 unsigned getCCRReg() const {
695 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
696 unsigned ClassID = Mips::CCRRegClassID;
697 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
700 /// Coerce the register to HWRegs and return the real register for the
702 unsigned getHWRegsReg() const {
703 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
704 unsigned ClassID = Mips::HWRegsRegClassID;
705 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
709 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
710 // Add as immediate when possible. Null MCExpr = 0.
712 Inst.addOperand(MCOperand::createImm(0));
713 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
714 Inst.addOperand(MCOperand::createImm(CE->getValue()));
716 Inst.addOperand(MCOperand::createExpr(Expr));
719 void addRegOperands(MCInst &Inst, unsigned N) const {
720 llvm_unreachable("Use a custom parser instead");
723 /// Render the operand to an MCInst as a GPR32
724 /// Asserts if the wrong number of operands are requested, or the operand
725 /// is not a k_RegisterIndex compatible with RegKind_GPR
726 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
727 assert(N == 1 && "Invalid number of operands!");
728 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
731 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
732 assert(N == 1 && "Invalid number of operands!");
733 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
736 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
737 assert(N == 1 && "Invalid number of operands!");
738 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
741 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
742 assert(N == 1 && "Invalid number of operands!");
743 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
746 /// Render the operand to an MCInst as a GPR64
747 /// Asserts if the wrong number of operands are requested, or the operand
748 /// is not a k_RegisterIndex compatible with RegKind_GPR
749 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
754 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
759 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
764 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
765 assert(N == 1 && "Invalid number of operands!");
766 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
767 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
768 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
769 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
773 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
774 assert(N == 1 && "Invalid number of operands!");
775 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
778 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::createReg(getFCCReg()));
783 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
788 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
789 assert(N == 1 && "Invalid number of operands!");
790 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
793 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
794 assert(N == 1 && "Invalid number of operands!");
795 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
798 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
799 assert(N == 1 && "Invalid number of operands!");
800 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
803 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
804 assert(N == 1 && "Invalid number of operands!");
805 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
808 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
809 assert(N == 1 && "Invalid number of operands!");
810 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
813 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 1 && "Invalid number of operands!");
815 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
818 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
819 assert(N == 1 && "Invalid number of operands!");
820 Inst.addOperand(MCOperand::createReg(getCCRReg()));
823 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
824 assert(N == 1 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
828 void addImmOperands(MCInst &Inst, unsigned N) const {
829 assert(N == 1 && "Invalid number of operands!");
830 const MCExpr *Expr = getImm();
834 void addMemOperands(MCInst &Inst, unsigned N) const {
835 assert(N == 2 && "Invalid number of operands!");
837 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
839 const MCExpr *Expr = getMemOff();
843 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
844 assert(N == 2 && "Invalid number of operands!");
846 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
848 const MCExpr *Expr = getMemOff();
852 void addRegListOperands(MCInst &Inst, unsigned N) const {
853 assert(N == 1 && "Invalid number of operands!");
855 for (auto RegNo : getRegList())
856 Inst.addOperand(MCOperand::createReg(RegNo));
859 void addRegPairOperands(MCInst &Inst, unsigned N) const {
860 assert(N == 2 && "Invalid number of operands!");
861 unsigned RegNo = getRegPair();
862 Inst.addOperand(MCOperand::createReg(RegNo++));
863 Inst.addOperand(MCOperand::createReg(RegNo));
866 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
867 assert(N == 2 && "Invalid number of operands!");
868 for (auto RegNo : getRegList())
869 Inst.addOperand(MCOperand::createReg(RegNo));
872 bool isReg() const override {
873 // As a special case until we sort out the definition of div/divu, pretend
874 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
875 if (isGPRAsmReg() && RegIdx.Index == 0)
878 return Kind == k_PhysRegister;
880 bool isRegIdx() const { return Kind == k_RegisterIndex; }
881 bool isImm() const override { return Kind == k_Immediate; }
882 bool isConstantImm() const {
883 return isImm() && dyn_cast<MCConstantExpr>(getImm());
885 template <unsigned Bits> bool isUImm() const {
886 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
888 bool isToken() const override {
889 // Note: It's not possible to pretend that other operand kinds are tokens.
890 // The matcher emitter checks tokens first.
891 return Kind == k_Token;
893 bool isMem() const override { return Kind == k_Memory; }
894 bool isConstantMemOff() const {
895 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
897 template <unsigned Bits> bool isMemWithSimmOffset() const {
898 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
900 bool isMemWithGRPMM16Base() const {
901 return isMem() && getMemBase()->isMM16AsmReg();
903 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
904 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
905 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
907 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
908 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
909 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
910 && (getMemBase()->getGPR32Reg() == Mips::SP);
912 bool isRegList16() const {
916 int Size = RegList.List->size();
917 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
918 RegList.List->back() != Mips::RA)
921 int PrevReg = *RegList.List->begin();
922 for (int i = 1; i < Size - 1; i++) {
923 int Reg = (*(RegList.List))[i];
924 if ( Reg != PrevReg + 1)
931 bool isInvNum() const { return Kind == k_Immediate; }
932 bool isLSAImm() const {
933 if (!isConstantImm())
935 int64_t Val = getConstantImm();
936 return 1 <= Val && Val <= 4;
938 bool isRegList() const { return Kind == k_RegList; }
939 bool isMovePRegPair() const {
940 if (Kind != k_RegList || RegList.List->size() != 2)
943 unsigned R0 = RegList.List->front();
944 unsigned R1 = RegList.List->back();
946 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
947 (R0 == Mips::A1 && R1 == Mips::A3) ||
948 (R0 == Mips::A2 && R1 == Mips::A3) ||
949 (R0 == Mips::A0 && R1 == Mips::S5) ||
950 (R0 == Mips::A0 && R1 == Mips::S6) ||
951 (R0 == Mips::A0 && R1 == Mips::A1) ||
952 (R0 == Mips::A0 && R1 == Mips::A2) ||
953 (R0 == Mips::A0 && R1 == Mips::A3))
959 StringRef getToken() const {
960 assert(Kind == k_Token && "Invalid access!");
961 return StringRef(Tok.Data, Tok.Length);
963 bool isRegPair() const { return Kind == k_RegPair; }
965 unsigned getReg() const override {
966 // As a special case until we sort out the definition of div/divu, pretend
967 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
968 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
969 RegIdx.Kind & RegKind_GPR)
970 return getGPR32Reg(); // FIXME: GPR64 too
972 assert(Kind == k_PhysRegister && "Invalid access!");
976 const MCExpr *getImm() const {
977 assert((Kind == k_Immediate) && "Invalid access!");
981 int64_t getConstantImm() const {
982 const MCExpr *Val = getImm();
983 return static_cast<const MCConstantExpr *>(Val)->getValue();
986 MipsOperand *getMemBase() const {
987 assert((Kind == k_Memory) && "Invalid access!");
991 const MCExpr *getMemOff() const {
992 assert((Kind == k_Memory) && "Invalid access!");
996 int64_t getConstantMemOff() const {
997 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1000 const SmallVectorImpl<unsigned> &getRegList() const {
1001 assert((Kind == k_RegList) && "Invalid access!");
1002 return *(RegList.List);
1005 unsigned getRegPair() const {
1006 assert((Kind == k_RegPair) && "Invalid access!");
1007 return RegIdx.Index;
1010 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1011 MipsAsmParser &Parser) {
1012 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1013 Op->Tok.Data = Str.data();
1014 Op->Tok.Length = Str.size();
1020 /// Create a numeric register (e.g. $1). The exact register remains
1021 /// unresolved until an instruction successfully matches
1022 static std::unique_ptr<MipsOperand>
1023 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1024 SMLoc E, MipsAsmParser &Parser) {
1025 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1026 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1029 /// Create a register that is definitely a GPR.
1030 /// This is typically only used for named registers such as $gp.
1031 static std::unique_ptr<MipsOperand>
1032 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1033 MipsAsmParser &Parser) {
1034 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1037 /// Create a register that is definitely a FGR.
1038 /// This is typically only used for named registers such as $f0.
1039 static std::unique_ptr<MipsOperand>
1040 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1041 MipsAsmParser &Parser) {
1042 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1045 /// Create a register that is definitely a HWReg.
1046 /// This is typically only used for named registers such as $hwr_cpunum.
1047 static std::unique_ptr<MipsOperand>
1048 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1049 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1050 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1053 /// Create a register that is definitely an FCC.
1054 /// This is typically only used for named registers such as $fcc0.
1055 static std::unique_ptr<MipsOperand>
1056 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1057 MipsAsmParser &Parser) {
1058 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1061 /// Create a register that is definitely an ACC.
1062 /// This is typically only used for named registers such as $ac0.
1063 static std::unique_ptr<MipsOperand>
1064 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1065 MipsAsmParser &Parser) {
1066 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1069 /// Create a register that is definitely an MSA128.
1070 /// This is typically only used for named registers such as $w0.
1071 static std::unique_ptr<MipsOperand>
1072 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1073 SMLoc E, MipsAsmParser &Parser) {
1074 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1077 /// Create a register that is definitely an MSACtrl.
1078 /// This is typically only used for named registers such as $msaaccess.
1079 static std::unique_ptr<MipsOperand>
1080 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1081 SMLoc E, MipsAsmParser &Parser) {
1082 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1085 static std::unique_ptr<MipsOperand>
1086 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1087 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1094 static std::unique_ptr<MipsOperand>
1095 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1096 SMLoc E, MipsAsmParser &Parser) {
1097 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1098 Op->Mem.Base = Base.release();
1105 static std::unique_ptr<MipsOperand>
1106 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1107 MipsAsmParser &Parser) {
1108 assert (Regs.size() > 0 && "Empty list not allowed");
1110 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1111 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1112 Op->StartLoc = StartLoc;
1113 Op->EndLoc = EndLoc;
1117 static std::unique_ptr<MipsOperand>
1118 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1119 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1120 Op->RegIdx.Index = RegNo;
1126 bool isGPRAsmReg() const {
1127 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1129 bool isMM16AsmReg() const {
1130 if (!(isRegIdx() && RegIdx.Kind))
1132 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1133 || RegIdx.Index == 16 || RegIdx.Index == 17);
1135 bool isMM16AsmRegZero() const {
1136 if (!(isRegIdx() && RegIdx.Kind))
1138 return (RegIdx.Index == 0 ||
1139 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1140 RegIdx.Index == 17);
1142 bool isMM16AsmRegMoveP() const {
1143 if (!(isRegIdx() && RegIdx.Kind))
1145 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1146 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1148 bool isFGRAsmReg() const {
1149 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1150 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1152 bool isHWRegsAsmReg() const {
1153 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1155 bool isCCRAsmReg() const {
1156 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1158 bool isFCCAsmReg() const {
1159 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1161 if (!AsmParser.hasEightFccRegisters())
1162 return RegIdx.Index == 0;
1163 return RegIdx.Index <= 7;
1165 bool isACCAsmReg() const {
1166 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1168 bool isCOP2AsmReg() const {
1169 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1171 bool isCOP3AsmReg() const {
1172 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1174 bool isMSA128AsmReg() const {
1175 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1177 bool isMSACtrlAsmReg() const {
1178 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1181 /// getStartLoc - Get the location of the first token of this operand.
1182 SMLoc getStartLoc() const override { return StartLoc; }
1183 /// getEndLoc - Get the location of the last token of this operand.
1184 SMLoc getEndLoc() const override { return EndLoc; }
1186 virtual ~MipsOperand() {
1194 delete RegList.List;
1195 case k_PhysRegister:
1196 case k_RegisterIndex:
1203 void print(raw_ostream &OS) const override {
1212 Mem.Base->print(OS);
1217 case k_PhysRegister:
1218 OS << "PhysReg<" << PhysReg.Num << ">";
1220 case k_RegisterIndex:
1221 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1228 for (auto Reg : (*RegList.List))
1233 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1237 }; // class MipsOperand
1241 extern const MCInstrDesc MipsInsts[];
1243 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1244 return MipsInsts[Opcode];
1247 static bool hasShortDelaySlot(unsigned Opcode) {
1250 case Mips::JALRS_MM:
1251 case Mips::JALRS16_MM:
1252 case Mips::BGEZALS_MM:
1253 case Mips::BLTZALS_MM:
1260 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1261 SmallVectorImpl<MCInst> &Instructions) {
1262 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1266 if (MCID.isBranch() || MCID.isCall()) {
1267 const unsigned Opcode = Inst.getOpcode();
1277 assert(hasCnMips() && "instruction only valid for octeon cpus");
1284 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1285 Offset = Inst.getOperand(2);
1286 if (!Offset.isImm())
1287 break; // We'll deal with this situation later on when applying fixups.
1288 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1289 return Error(IDLoc, "branch target out of range");
1290 if (OffsetToAlignment(Offset.getImm(),
1291 1LL << (inMicroMipsMode() ? 1 : 2)))
1292 return Error(IDLoc, "branch to misaligned address");
1306 case Mips::BGEZAL_MM:
1307 case Mips::BLTZAL_MM:
1310 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1311 Offset = Inst.getOperand(1);
1312 if (!Offset.isImm())
1313 break; // We'll deal with this situation later on when applying fixups.
1314 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1315 return Error(IDLoc, "branch target out of range");
1316 if (OffsetToAlignment(Offset.getImm(),
1317 1LL << (inMicroMipsMode() ? 1 : 2)))
1318 return Error(IDLoc, "branch to misaligned address");
1320 case Mips::BEQZ16_MM:
1321 case Mips::BNEZ16_MM:
1322 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1323 Offset = Inst.getOperand(1);
1324 if (!Offset.isImm())
1325 break; // We'll deal with this situation later on when applying fixups.
1326 if (!isIntN(8, Offset.getImm()))
1327 return Error(IDLoc, "branch target out of range");
1328 if (OffsetToAlignment(Offset.getImm(), 2LL))
1329 return Error(IDLoc, "branch to misaligned address");
1334 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1335 // We still accept it but it is a normal nop.
1336 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1337 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1338 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1343 const unsigned Opcode = Inst.getOpcode();
1355 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1356 // The offset is handled above
1357 Opnd = Inst.getOperand(1);
1359 return Error(IDLoc, "expected immediate operand kind");
1360 Imm = Opnd.getImm();
1361 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1362 Opcode == Mips::BBIT1 ? 63 : 31))
1363 return Error(IDLoc, "immediate operand value out of range");
1365 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1367 Inst.getOperand(1).setImm(Imm - 32);
1375 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1377 Opnd = Inst.getOperand(3);
1379 return Error(IDLoc, "expected immediate operand kind");
1380 Imm = Opnd.getImm();
1381 if (Imm < 0 || Imm > 31)
1382 return Error(IDLoc, "immediate operand value out of range");
1384 Opnd = Inst.getOperand(2);
1386 return Error(IDLoc, "expected immediate operand kind");
1387 Imm = Opnd.getImm();
1388 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1389 Opcode == Mips::EXTS ? 63 : 31))
1390 return Error(IDLoc, "immediate operand value out of range");
1392 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1393 Inst.getOperand(2).setImm(Imm - 32);
1399 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1400 Opnd = Inst.getOperand(2);
1402 return Error(IDLoc, "expected immediate operand kind");
1403 Imm = Opnd.getImm();
1404 if (!isInt<10>(Imm))
1405 return Error(IDLoc, "immediate operand value out of range");
1410 if (MCID.mayLoad() || MCID.mayStore()) {
1411 // Check the offset of memory operand, if it is a symbol
1412 // reference or immediate we may have to expand instructions.
1413 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1414 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1415 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1416 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1417 MCOperand &Op = Inst.getOperand(i);
1419 int MemOffset = Op.getImm();
1420 if (MemOffset < -32768 || MemOffset > 32767) {
1421 // Offset can't exceed 16bit value.
1422 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1425 } else if (Op.isExpr()) {
1426 const MCExpr *Expr = Op.getExpr();
1427 if (Expr->getKind() == MCExpr::SymbolRef) {
1428 const MCSymbolRefExpr *SR =
1429 static_cast<const MCSymbolRefExpr *>(Expr);
1430 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1432 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1435 } else if (!isEvaluated(Expr)) {
1436 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1444 if (inMicroMipsMode()) {
1445 if (MCID.mayLoad()) {
1446 // Try to create 16-bit GP relative load instruction.
1447 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1448 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1449 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1450 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1451 MCOperand &Op = Inst.getOperand(i);
1453 int MemOffset = Op.getImm();
1454 MCOperand &DstReg = Inst.getOperand(0);
1455 MCOperand &BaseReg = Inst.getOperand(1);
1456 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1457 getContext().getRegisterInfo()->getRegClass(
1458 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1459 BaseReg.getReg() == Mips::GP) {
1461 TmpInst.setLoc(IDLoc);
1462 TmpInst.setOpcode(Mips::LWGP_MM);
1463 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1464 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1465 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1466 Instructions.push_back(TmpInst);
1474 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1479 switch (Inst.getOpcode()) {
1482 case Mips::ADDIUS5_MM:
1483 Opnd = Inst.getOperand(2);
1485 return Error(IDLoc, "expected immediate operand kind");
1486 Imm = Opnd.getImm();
1487 if (Imm < -8 || Imm > 7)
1488 return Error(IDLoc, "immediate operand value out of range");
1490 case Mips::ADDIUSP_MM:
1491 Opnd = Inst.getOperand(0);
1493 return Error(IDLoc, "expected immediate operand kind");
1494 Imm = Opnd.getImm();
1495 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1497 return Error(IDLoc, "immediate operand value out of range");
1499 case Mips::SLL16_MM:
1500 case Mips::SRL16_MM:
1501 Opnd = Inst.getOperand(2);
1503 return Error(IDLoc, "expected immediate operand kind");
1504 Imm = Opnd.getImm();
1505 if (Imm < 1 || Imm > 8)
1506 return Error(IDLoc, "immediate operand value out of range");
1509 Opnd = Inst.getOperand(1);
1511 return Error(IDLoc, "expected immediate operand kind");
1512 Imm = Opnd.getImm();
1513 if (Imm < -1 || Imm > 126)
1514 return Error(IDLoc, "immediate operand value out of range");
1516 case Mips::ADDIUR2_MM:
1517 Opnd = Inst.getOperand(2);
1519 return Error(IDLoc, "expected immediate operand kind");
1520 Imm = Opnd.getImm();
1521 if (!(Imm == 1 || Imm == -1 ||
1522 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1523 return Error(IDLoc, "immediate operand value out of range");
1525 case Mips::ADDIUR1SP_MM:
1526 Opnd = Inst.getOperand(1);
1528 return Error(IDLoc, "expected immediate operand kind");
1529 Imm = Opnd.getImm();
1530 if (OffsetToAlignment(Imm, 4LL))
1531 return Error(IDLoc, "misaligned immediate operand value");
1532 if (Imm < 0 || Imm > 255)
1533 return Error(IDLoc, "immediate operand value out of range");
1535 case Mips::ANDI16_MM:
1536 Opnd = Inst.getOperand(2);
1538 return Error(IDLoc, "expected immediate operand kind");
1539 Imm = Opnd.getImm();
1540 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1541 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1542 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1543 return Error(IDLoc, "immediate operand value out of range");
1545 case Mips::LBU16_MM:
1546 Opnd = Inst.getOperand(2);
1548 return Error(IDLoc, "expected immediate operand kind");
1549 Imm = Opnd.getImm();
1550 if (Imm < -1 || Imm > 14)
1551 return Error(IDLoc, "immediate operand value out of range");
1554 Opnd = Inst.getOperand(2);
1556 return Error(IDLoc, "expected immediate operand kind");
1557 Imm = Opnd.getImm();
1558 if (Imm < 0 || Imm > 15)
1559 return Error(IDLoc, "immediate operand value out of range");
1561 case Mips::LHU16_MM:
1563 Opnd = Inst.getOperand(2);
1565 return Error(IDLoc, "expected immediate operand kind");
1566 Imm = Opnd.getImm();
1567 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1568 return Error(IDLoc, "immediate operand value out of range");
1572 Opnd = Inst.getOperand(2);
1574 return Error(IDLoc, "expected immediate operand kind");
1575 Imm = Opnd.getImm();
1576 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1577 return Error(IDLoc, "immediate operand value out of range");
1581 Opnd = Inst.getOperand(2);
1583 return Error(IDLoc, "expected immediate operand kind");
1584 Imm = Opnd.getImm();
1585 if (!isUInt<5>(Imm))
1586 return Error(IDLoc, "immediate operand value out of range");
1588 case Mips::ADDIUPC_MM:
1589 MCOperand Opnd = Inst.getOperand(1);
1591 return Error(IDLoc, "expected immediate operand kind");
1592 int Imm = Opnd.getImm();
1593 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1594 return Error(IDLoc, "immediate operand value out of range");
1599 if (needsExpansion(Inst)) {
1600 if (expandInstruction(Inst, IDLoc, Instructions))
1603 Instructions.push_back(Inst);
1605 // If this instruction has a delay slot and .set reorder is active,
1606 // emit a NOP after it.
1607 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1608 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1613 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1615 switch (Inst.getOpcode()) {
1616 case Mips::LoadImm32:
1617 case Mips::LoadImm64:
1618 case Mips::LoadAddrImm32:
1619 case Mips::LoadAddrReg32:
1620 case Mips::B_MM_Pseudo:
1623 case Mips::JalOneReg:
1624 case Mips::JalTwoReg:
1633 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1634 SmallVectorImpl<MCInst> &Instructions) {
1635 switch (Inst.getOpcode()) {
1636 default: llvm_unreachable("unimplemented expansion");
1637 case Mips::LoadImm32:
1638 return expandLoadImm(Inst, true, IDLoc, Instructions);
1639 case Mips::LoadImm64:
1640 return expandLoadImm(Inst, false, IDLoc, Instructions);
1641 case Mips::LoadAddrImm32:
1642 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1643 case Mips::LoadAddrReg32:
1644 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1645 case Mips::B_MM_Pseudo:
1646 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1649 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1650 case Mips::JalOneReg:
1651 case Mips::JalTwoReg:
1652 return expandJalWithRegs(Inst, IDLoc, Instructions);
1655 return expandBranchImm(Inst, IDLoc, Instructions);
1660 template <unsigned ShiftAmount>
1661 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1662 SmallVectorImpl<MCInst> &Instructions) {
1664 if (ShiftAmount >= 32) {
1665 tmpInst.setOpcode(Mips::DSLL32);
1666 tmpInst.addOperand(MCOperand::createReg(RegNo));
1667 tmpInst.addOperand(MCOperand::createReg(RegNo));
1668 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1669 tmpInst.setLoc(IDLoc);
1670 Instructions.push_back(tmpInst);
1672 } else if (ShiftAmount > 0) {
1673 tmpInst.setOpcode(Mips::DSLL);
1674 tmpInst.addOperand(MCOperand::createReg(RegNo));
1675 tmpInst.addOperand(MCOperand::createReg(RegNo));
1676 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1677 tmpInst.setLoc(IDLoc);
1678 Instructions.push_back(tmpInst);
1681 // There's no need for an ORi if the immediate is 0.
1682 if (Operand.isImm() && Operand.getImm() == 0)
1685 tmpInst.setOpcode(Mips::ORi);
1686 tmpInst.addOperand(MCOperand::createReg(RegNo));
1687 tmpInst.addOperand(MCOperand::createReg(RegNo));
1688 tmpInst.addOperand(Operand);
1689 tmpInst.setLoc(IDLoc);
1690 Instructions.push_back(tmpInst);
1693 template <unsigned ShiftAmount>
1694 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1695 SmallVectorImpl<MCInst> &Instructions) {
1696 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1701 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1702 SmallVectorImpl<MCInst> &Instructions) {
1703 // Create a JALR instruction which is going to replace the pseudo-JAL.
1705 JalrInst.setLoc(IDLoc);
1706 const MCOperand FirstRegOp = Inst.getOperand(0);
1707 const unsigned Opcode = Inst.getOpcode();
1709 if (Opcode == Mips::JalOneReg) {
1710 // jal $rs => jalr $rs
1711 if (inMicroMipsMode()) {
1712 JalrInst.setOpcode(Mips::JALR16_MM);
1713 JalrInst.addOperand(FirstRegOp);
1715 JalrInst.setOpcode(Mips::JALR);
1716 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1717 JalrInst.addOperand(FirstRegOp);
1719 } else if (Opcode == Mips::JalTwoReg) {
1720 // jal $rd, $rs => jalr $rd, $rs
1721 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1722 JalrInst.addOperand(FirstRegOp);
1723 const MCOperand SecondRegOp = Inst.getOperand(1);
1724 JalrInst.addOperand(SecondRegOp);
1726 Instructions.push_back(JalrInst);
1728 // If .set reorder is active, emit a NOP after it.
1729 if (AssemblerOptions.back()->isReorder()) {
1730 // This is a 32-bit NOP because these 2 pseudo-instructions
1731 // do not have a short delay slot.
1733 NopInst.setOpcode(Mips::SLL);
1734 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1735 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1736 NopInst.addOperand(MCOperand::createImm(0));
1737 Instructions.push_back(NopInst);
1743 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1744 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1745 SmallVectorImpl<MCInst> &Instructions) {
1746 if (!Is32BitImm && !isGP64bit()) {
1747 Error(IDLoc, "instruction requires a 64-bit architecture");
1751 bool UseSrcReg = false;
1752 if (SrcReg != Mips::NoRegister)
1757 tmpInst.setLoc(IDLoc);
1758 // FIXME: gas has a special case for values that are 000...1111, which
1759 // becomes a li -1 and then a dsrl
1760 if (0 <= ImmValue && ImmValue <= 65535) {
1761 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1762 // li d,j => ori d,$zero,j
1764 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1765 tmpInst.setOpcode(Mips::ORi);
1766 tmpInst.addOperand(MCOperand::createReg(DstReg));
1767 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1768 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1769 Instructions.push_back(tmpInst);
1770 } else if (ImmValue < 0 && ImmValue >= -32768) {
1771 // For negative signed 16-bit values (-32768 <= j < 0):
1772 // li d,j => addiu d,$zero,j
1774 SrcReg = Mips::ZERO;
1775 tmpInst.setOpcode(Mips::ADDiu);
1776 tmpInst.addOperand(MCOperand::createReg(DstReg));
1777 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1778 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1779 Instructions.push_back(tmpInst);
1780 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1781 warnIfNoMacro(IDLoc);
1783 // For all other values which are representable as a 32-bit integer:
1784 // li d,j => lui d,hi16(j)
1786 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1787 uint16_t Bits15To0 = ImmValue & 0xffff;
1789 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1790 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1792 tmpInst.setOpcode(Mips::ORi);
1793 tmpInst.addOperand(MCOperand::createReg(DstReg));
1794 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1795 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1796 tmpInst.setLoc(IDLoc);
1797 Instructions.push_back(tmpInst);
1798 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1799 createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
1801 tmpInst.setOpcode(Mips::LUi);
1802 tmpInst.addOperand(MCOperand::createReg(DstReg));
1803 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1804 Instructions.push_back(tmpInst);
1806 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1809 createAddu(DstReg, DstReg, SrcReg, Instructions);
1811 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1813 Error(IDLoc, "instruction requires a 32-bit immediate");
1816 warnIfNoMacro(IDLoc);
1818 // <------- lo32 ------>
1819 // <------- hi32 ------>
1820 // <- hi16 -> <- lo16 ->
1821 // _________________________________
1823 // | 16-bits | 16-bits | 16-bits |
1824 // |__________|__________|__________|
1826 // For any 64-bit value that is representable as a 48-bit integer:
1827 // li d,j => lui d,hi16(j)
1828 // ori d,d,hi16(lo32(j))
1830 // ori d,d,lo16(lo32(j))
1831 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1832 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1833 uint16_t Bits15To0 = ImmValue & 0xffff;
1835 tmpInst.setOpcode(Mips::LUi);
1836 tmpInst.addOperand(MCOperand::createReg(DstReg));
1837 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1838 Instructions.push_back(tmpInst);
1839 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1840 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1843 createAddu(DstReg, DstReg, SrcReg, Instructions);
1847 Error(IDLoc, "instruction requires a 32-bit immediate");
1850 warnIfNoMacro(IDLoc);
1852 // <------- hi32 ------> <------- lo32 ------>
1853 // <- hi16 -> <- lo16 ->
1854 // ___________________________________________
1856 // | 16-bits | 16-bits | 16-bits | 16-bits |
1857 // |__________|__________|__________|__________|
1859 // For all other values which are representable as a 64-bit integer:
1860 // li d,j => lui d,hi16(j)
1861 // ori d,d,lo16(hi32(j))
1863 // ori d,d,hi16(lo32(j))
1865 // ori d,d,lo16(lo32(j))
1866 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1867 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1868 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1869 uint16_t Bits15To0 = ImmValue & 0xffff;
1871 tmpInst.setOpcode(Mips::LUi);
1872 tmpInst.addOperand(MCOperand::createReg(DstReg));
1873 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1874 Instructions.push_back(tmpInst);
1875 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1877 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1878 // two left shifts of 16 bits.
1879 if (Bits31To16 == 0) {
1880 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1882 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1883 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1887 createAddu(DstReg, DstReg, SrcReg, Instructions);
1892 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1893 SmallVectorImpl<MCInst> &Instructions) {
1894 const MCOperand &ImmOp = Inst.getOperand(1);
1895 assert(ImmOp.isImm() && "expected immediate operand kind");
1896 const MCOperand &DstRegOp = Inst.getOperand(0);
1897 assert(DstRegOp.isReg() && "expected register operand kind");
1899 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1900 Is32BitImm, IDLoc, Instructions))
1907 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1908 SmallVectorImpl<MCInst> &Instructions) {
1909 const MCOperand &DstRegOp = Inst.getOperand(0);
1910 assert(DstRegOp.isReg() && "expected register operand kind");
1912 const MCOperand &ImmOp = Inst.getOperand(2);
1913 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1914 "expected immediate operand kind");
1915 if (!ImmOp.isImm()) {
1916 if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Is32BitImm, IDLoc,
1922 const MCOperand &SrcRegOp = Inst.getOperand(1);
1923 assert(SrcRegOp.isReg() && "expected register operand kind");
1925 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1926 Is32BitImm, IDLoc, Instructions))
1933 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1934 SmallVectorImpl<MCInst> &Instructions) {
1935 const MCOperand &DstRegOp = Inst.getOperand(0);
1936 assert(DstRegOp.isReg() && "expected register operand kind");
1938 const MCOperand &ImmOp = Inst.getOperand(1);
1939 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1940 "expected immediate operand kind");
1941 if (!ImmOp.isImm()) {
1942 if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Is32BitImm, IDLoc,
1949 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1950 Is32BitImm, IDLoc, Instructions))
1956 bool MipsAsmParser::loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
1957 bool Is32BitSym, SMLoc IDLoc,
1958 SmallVectorImpl<MCInst> &Instructions) {
1959 warnIfNoMacro(IDLoc);
1961 if (Is32BitSym && isABI_N64())
1962 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1965 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
1966 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
1967 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1968 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
1969 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1972 // If it's a 64-bit architecture, expand to:
1973 // la d,sym => lui d,highest(sym)
1974 // ori d,d,higher(sym)
1976 // ori d,d,hi16(sym)
1978 // ori d,d,lo16(sym)
1979 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
1980 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1981 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
1982 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1984 tmpInst.setOpcode(Mips::LUi);
1985 tmpInst.addOperand(MCOperand::createReg(DstReg));
1986 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1987 Instructions.push_back(tmpInst);
1989 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), DstReg, SMLoc(),
1991 createLShiftOri<16>(MCOperand::createExpr(HiExpr), DstReg, SMLoc(),
1993 createLShiftOri<16>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(),
1996 // Otherwise, expand to:
1997 // la d,sym => lui d,hi16(sym)
1998 // ori d,d,lo16(sym)
1999 tmpInst.setOpcode(Mips::LUi);
2000 tmpInst.addOperand(MCOperand::createReg(DstReg));
2001 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2002 Instructions.push_back(tmpInst);
2004 createLShiftOri<0>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(),
2010 bool MipsAsmParser::expandUncondBranchMMPseudo(
2011 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2012 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2013 "unexpected number of operands");
2015 MCOperand Offset = Inst.getOperand(0);
2016 if (Offset.isExpr()) {
2018 Inst.setOpcode(Mips::BEQ_MM);
2019 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2020 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2021 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2023 assert(Offset.isImm() && "expected immediate operand kind");
2024 if (isIntN(11, Offset.getImm())) {
2025 // If offset fits into 11 bits then this instruction becomes microMIPS
2026 // 16-bit unconditional branch instruction.
2027 Inst.setOpcode(Mips::B16_MM);
2029 if (!isIntN(17, Offset.getImm()))
2030 Error(IDLoc, "branch target out of range");
2031 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2032 Error(IDLoc, "branch to misaligned address");
2034 Inst.setOpcode(Mips::BEQ_MM);
2035 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2036 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2037 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2040 Instructions.push_back(Inst);
2042 // If .set reorder is active, emit a NOP after the branch instruction.
2043 if (AssemblerOptions.back()->isReorder())
2044 createNop(true, IDLoc, Instructions);
2049 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2050 SmallVectorImpl<MCInst> &Instructions) {
2051 const MCOperand &DstRegOp = Inst.getOperand(0);
2052 assert(DstRegOp.isReg() && "expected register operand kind");
2054 const MCOperand &ImmOp = Inst.getOperand(1);
2055 assert(ImmOp.isImm() && "expected immediate operand kind");
2057 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2058 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2060 unsigned OpCode = 0;
2061 switch(Inst.getOpcode()) {
2069 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2073 int64_t ImmValue = ImmOp.getImm();
2074 if (ImmValue == 0) {
2076 BranchInst.setOpcode(OpCode);
2077 BranchInst.addOperand(DstRegOp);
2078 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2079 BranchInst.addOperand(MemOffsetOp);
2080 Instructions.push_back(BranchInst);
2082 warnIfNoMacro(IDLoc);
2084 unsigned ATReg = getATReg(IDLoc);
2088 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2093 BranchInst.setOpcode(OpCode);
2094 BranchInst.addOperand(DstRegOp);
2095 BranchInst.addOperand(MCOperand::createReg(ATReg));
2096 BranchInst.addOperand(MemOffsetOp);
2097 Instructions.push_back(BranchInst);
2102 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2103 SmallVectorImpl<MCInst> &Instructions,
2104 bool isLoad, bool isImmOpnd) {
2106 unsigned ImmOffset, HiOffset, LoOffset;
2107 const MCExpr *ExprOffset;
2109 // 1st operand is either the source or destination register.
2110 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2111 unsigned RegOpNum = Inst.getOperand(0).getReg();
2112 // 2nd operand is the base register.
2113 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2114 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2115 // 3rd operand is either an immediate or expression.
2117 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2118 ImmOffset = Inst.getOperand(2).getImm();
2119 LoOffset = ImmOffset & 0x0000ffff;
2120 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2121 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2122 if (LoOffset & 0x8000)
2125 ExprOffset = Inst.getOperand(2).getExpr();
2126 // All instructions will have the same location.
2127 TempInst.setLoc(IDLoc);
2128 // These are some of the types of expansions we perform here:
2129 // 1) lw $8, sym => lui $8, %hi(sym)
2130 // lw $8, %lo(sym)($8)
2131 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2133 // lw $8, %lo(offset)($9)
2134 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2136 // lw $8, %lo(offset)($at)
2137 // 4) sw $8, sym => lui $at, %hi(sym)
2138 // sw $8, %lo(sym)($at)
2139 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2141 // sw $8, %lo(offset)($at)
2142 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2143 // ldc1 $f0, %lo(sym)($at)
2145 // For load instructions we can use the destination register as a temporary
2146 // if base and dst are different (examples 1 and 2) and if the base register
2147 // is general purpose otherwise we must use $at (example 6) and error if it's
2148 // not available. For stores we must use $at (examples 4 and 5) because we
2149 // must not clobber the source register setting up the offset.
2150 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2151 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2152 unsigned RegClassIDOp0 =
2153 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2154 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2155 (RegClassIDOp0 == Mips::GPR64RegClassID);
2156 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2157 TmpRegNum = RegOpNum;
2159 // At this point we need AT to perform the expansions and we exit if it is
2161 TmpRegNum = getATReg(IDLoc);
2166 TempInst.setOpcode(Mips::LUi);
2167 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2169 TempInst.addOperand(MCOperand::createImm(HiOffset));
2171 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2172 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2174 // Add the instruction to the list.
2175 Instructions.push_back(TempInst);
2176 // Prepare TempInst for next instruction.
2178 // Add temp register to base.
2179 if (BaseRegNum != Mips::ZERO) {
2180 TempInst.setOpcode(Mips::ADDu);
2181 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2182 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2183 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2184 Instructions.push_back(TempInst);
2187 // And finally, create original instruction with low part
2188 // of offset and new base.
2189 TempInst.setOpcode(Inst.getOpcode());
2190 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2191 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2193 TempInst.addOperand(MCOperand::createImm(LoOffset));
2195 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2196 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2198 Instructions.push_back(TempInst);
2203 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2204 SmallVectorImpl<MCInst> &Instructions) {
2205 unsigned OpNum = Inst.getNumOperands();
2206 unsigned Opcode = Inst.getOpcode();
2207 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2209 assert (Inst.getOperand(OpNum - 1).isImm() &&
2210 Inst.getOperand(OpNum - 2).isReg() &&
2211 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2213 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2214 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2215 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2216 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2217 // It can be implemented as SWM16 or LWM16 instruction.
2218 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2220 Inst.setOpcode(NewOpcode);
2221 Instructions.push_back(Inst);
2225 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2226 SmallVectorImpl<MCInst> &Instructions) {
2228 if (hasShortDelaySlot) {
2229 NopInst.setOpcode(Mips::MOVE16_MM);
2230 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2231 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2233 NopInst.setOpcode(Mips::SLL);
2234 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2235 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2236 NopInst.addOperand(MCOperand::createImm(0));
2238 Instructions.push_back(NopInst);
2241 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2243 SmallVectorImpl<MCInst> &Instructions) {
2245 AdduInst.setOpcode(Mips::ADDu);
2246 AdduInst.addOperand(MCOperand::createReg(DstReg));
2247 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2248 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2249 Instructions.push_back(AdduInst);
2252 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2253 // As described by the Mips32r2 spec, the registers Rd and Rs for
2254 // jalr.hb must be different.
2255 unsigned Opcode = Inst.getOpcode();
2257 if (Opcode == Mips::JALR_HB &&
2258 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2259 return Match_RequiresDifferentSrcAndDst;
2261 return Match_Success;
2264 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2265 OperandVector &Operands,
2267 uint64_t &ErrorInfo,
2268 bool MatchingInlineAsm) {
2271 SmallVector<MCInst, 8> Instructions;
2272 unsigned MatchResult =
2273 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2275 switch (MatchResult) {
2276 case Match_Success: {
2277 if (processInstruction(Inst, IDLoc, Instructions))
2279 for (unsigned i = 0; i < Instructions.size(); i++)
2280 Out.EmitInstruction(Instructions[i], STI);
2283 case Match_MissingFeature:
2284 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2286 case Match_InvalidOperand: {
2287 SMLoc ErrorLoc = IDLoc;
2288 if (ErrorInfo != ~0ULL) {
2289 if (ErrorInfo >= Operands.size())
2290 return Error(IDLoc, "too few operands for instruction");
2292 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2293 if (ErrorLoc == SMLoc())
2297 return Error(ErrorLoc, "invalid operand for instruction");
2299 case Match_MnemonicFail:
2300 return Error(IDLoc, "invalid instruction");
2301 case Match_RequiresDifferentSrcAndDst:
2302 return Error(IDLoc, "source and destination must be different");
2305 llvm_unreachable("Implement any new match types added!");
2308 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2309 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2310 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2311 ") without \".set noat\"");
2314 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2315 if (!AssemblerOptions.back()->isMacro())
2316 Warning(Loc, "macro instruction expanded into multiple instructions");
2320 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2321 SMRange Range, bool ShowColors) {
2322 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2323 Range, SMFixIt(Range, FixMsg),
2327 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2330 CC = StringSwitch<unsigned>(Name)
2366 if (!(isABI_N32() || isABI_N64()))
2369 if (12 <= CC && CC <= 15) {
2370 // Name is one of t4-t7
2371 AsmToken RegTok = getLexer().peekTok();
2372 SMRange RegRange = RegTok.getLocRange();
2374 StringRef FixedName = StringSwitch<StringRef>(Name)
2380 assert(FixedName != "" && "Register name is not one of t4-t7.");
2382 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2383 "Did you mean $" + FixedName + "?", RegRange);
2386 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2387 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2388 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2389 if (8 <= CC && CC <= 11)
2393 CC = StringSwitch<unsigned>(Name)
2405 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2408 CC = StringSwitch<unsigned>(Name)
2409 .Case("hwr_cpunum", 0)
2410 .Case("hwr_synci_step", 1)
2412 .Case("hwr_ccres", 3)
2413 .Case("hwr_ulr", 29)
2419 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2421 if (Name[0] == 'f') {
2422 StringRef NumString = Name.substr(1);
2424 if (NumString.getAsInteger(10, IntVal))
2425 return -1; // This is not an integer.
2426 if (IntVal > 31) // Maximum index for fpu register.
2433 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2435 if (Name.startswith("fcc")) {
2436 StringRef NumString = Name.substr(3);
2438 if (NumString.getAsInteger(10, IntVal))
2439 return -1; // This is not an integer.
2440 if (IntVal > 7) // There are only 8 fcc registers.
2447 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2449 if (Name.startswith("ac")) {
2450 StringRef NumString = Name.substr(2);
2452 if (NumString.getAsInteger(10, IntVal))
2453 return -1; // This is not an integer.
2454 if (IntVal > 3) // There are only 3 acc registers.
2461 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2464 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2473 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2476 CC = StringSwitch<unsigned>(Name)
2479 .Case("msaaccess", 2)
2481 .Case("msamodify", 4)
2482 .Case("msarequest", 5)
2484 .Case("msaunmap", 7)
2490 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2491 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2493 reportParseError(Loc,
2494 "pseudo-instruction requires $at, which is not available");
2497 unsigned AT = getReg(
2498 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2502 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2503 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2506 unsigned MipsAsmParser::getGPR(int RegNo) {
2507 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2511 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2513 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2516 return getReg(RegClass, RegNum);
2519 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2520 MCAsmParser &Parser = getParser();
2521 DEBUG(dbgs() << "parseOperand\n");
2523 // Check if the current operand has a custom associated parser, if so, try to
2524 // custom parse the operand, or fallback to the general approach.
2525 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2526 if (ResTy == MatchOperand_Success)
2528 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2529 // there was a match, but an error occurred, in which case, just return that
2530 // the operand parsing failed.
2531 if (ResTy == MatchOperand_ParseFail)
2534 DEBUG(dbgs() << ".. Generic Parser\n");
2536 switch (getLexer().getKind()) {
2538 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2540 case AsmToken::Dollar: {
2541 // Parse the register.
2542 SMLoc S = Parser.getTok().getLoc();
2544 // Almost all registers have been parsed by custom parsers. There is only
2545 // one exception to this. $zero (and it's alias $0) will reach this point
2546 // for div, divu, and similar instructions because it is not an operand
2547 // to the instruction definition but an explicit register. Special case
2548 // this situation for now.
2549 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2552 // Maybe it is a symbol reference.
2553 StringRef Identifier;
2554 if (Parser.parseIdentifier(Identifier))
2557 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2558 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2559 // Otherwise create a symbol reference.
2561 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2563 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2566 // Else drop to expression parsing.
2567 case AsmToken::LParen:
2568 case AsmToken::Minus:
2569 case AsmToken::Plus:
2570 case AsmToken::Integer:
2571 case AsmToken::Tilde:
2572 case AsmToken::String: {
2573 DEBUG(dbgs() << ".. generic integer\n");
2574 OperandMatchResultTy ResTy = parseImm(Operands);
2575 return ResTy != MatchOperand_Success;
2577 case AsmToken::Percent: {
2578 // It is a symbol reference or constant expression.
2579 const MCExpr *IdVal;
2580 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2581 if (parseRelocOperand(IdVal))
2584 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2586 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2588 } // case AsmToken::Percent
2589 } // switch(getLexer().getKind())
2593 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2594 StringRef RelocStr) {
2596 // Check the type of the expression.
2597 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2598 // It's a constant, evaluate reloc value.
2600 switch (getVariantKind(RelocStr)) {
2601 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2602 // Get the 1st 16-bits.
2603 Val = MCE->getValue() & 0xffff;
2605 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2606 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2607 // 16 bits being negative.
2608 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2610 case MCSymbolRefExpr::VK_Mips_HIGHER:
2611 // Get the 3rd 16-bits.
2612 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2614 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2615 // Get the 4th 16-bits.
2616 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2619 report_fatal_error("unsupported reloc value");
2621 return MCConstantExpr::create(Val, getContext());
2624 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2625 // It's a symbol, create a symbolic expression from the symbol.
2626 const MCSymbol *Symbol = &MSRE->getSymbol();
2627 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2628 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
2632 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2633 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2635 // Try to create target expression.
2636 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2637 return MipsMCExpr::create(VK, Expr, getContext());
2639 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2640 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2641 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
2645 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2646 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2647 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
2650 // Just return the original expression.
2654 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2656 switch (Expr->getKind()) {
2657 case MCExpr::Constant:
2659 case MCExpr::SymbolRef:
2660 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2661 case MCExpr::Binary:
2662 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2663 if (!isEvaluated(BE->getLHS()))
2665 return isEvaluated(BE->getRHS());
2668 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2669 case MCExpr::Target:
2675 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2676 MCAsmParser &Parser = getParser();
2677 Parser.Lex(); // Eat the % token.
2678 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2679 if (Tok.isNot(AsmToken::Identifier))
2682 std::string Str = Tok.getIdentifier();
2684 Parser.Lex(); // Eat the identifier.
2685 // Now make an expression from the rest of the operand.
2686 const MCExpr *IdVal;
2689 if (getLexer().getKind() == AsmToken::LParen) {
2691 Parser.Lex(); // Eat the '(' token.
2692 if (getLexer().getKind() == AsmToken::Percent) {
2693 Parser.Lex(); // Eat the % token.
2694 const AsmToken &nextTok = Parser.getTok();
2695 if (nextTok.isNot(AsmToken::Identifier))
2698 Str += nextTok.getIdentifier();
2699 Parser.Lex(); // Eat the identifier.
2700 if (getLexer().getKind() != AsmToken::LParen)
2705 if (getParser().parseParenExpression(IdVal, EndLoc))
2708 while (getLexer().getKind() == AsmToken::RParen)
2709 Parser.Lex(); // Eat the ')' token.
2712 return true; // Parenthesis must follow the relocation operand.
2714 Res = evaluateRelocExpr(IdVal, Str);
2718 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2720 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2721 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2722 if (ResTy == MatchOperand_Success) {
2723 assert(Operands.size() == 1);
2724 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2725 StartLoc = Operand.getStartLoc();
2726 EndLoc = Operand.getEndLoc();
2728 // AFAIK, we only support numeric registers and named GPR's in CFI
2730 // Don't worry about eating tokens before failing. Using an unrecognised
2731 // register is a parse error.
2732 if (Operand.isGPRAsmReg()) {
2733 // Resolve to GPR32 or GPR64 appropriately.
2734 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2737 return (RegNo == (unsigned)-1);
2740 assert(Operands.size() == 0);
2741 return (RegNo == (unsigned)-1);
2744 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2745 MCAsmParser &Parser = getParser();
2749 while (getLexer().getKind() == AsmToken::LParen)
2752 switch (getLexer().getKind()) {
2755 case AsmToken::Identifier:
2756 case AsmToken::LParen:
2757 case AsmToken::Integer:
2758 case AsmToken::Minus:
2759 case AsmToken::Plus:
2761 Result = getParser().parseParenExpression(Res, S);
2763 Result = (getParser().parseExpression(Res));
2764 while (getLexer().getKind() == AsmToken::RParen)
2767 case AsmToken::Percent:
2768 Result = parseRelocOperand(Res);
2773 MipsAsmParser::OperandMatchResultTy
2774 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2775 MCAsmParser &Parser = getParser();
2776 DEBUG(dbgs() << "parseMemOperand\n");
2777 const MCExpr *IdVal = nullptr;
2779 bool isParenExpr = false;
2780 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2781 // First operand is the offset.
2782 S = Parser.getTok().getLoc();
2784 if (getLexer().getKind() == AsmToken::LParen) {
2789 if (getLexer().getKind() != AsmToken::Dollar) {
2790 if (parseMemOffset(IdVal, isParenExpr))
2791 return MatchOperand_ParseFail;
2793 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2794 if (Tok.isNot(AsmToken::LParen)) {
2795 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2796 if (Mnemonic.getToken() == "la") {
2798 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2799 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2800 return MatchOperand_Success;
2802 if (Tok.is(AsmToken::EndOfStatement)) {
2804 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2806 // Zero register assumed, add a memory operand with ZERO as its base.
2807 // "Base" will be managed by k_Memory.
2808 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2811 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2812 return MatchOperand_Success;
2814 Error(Parser.getTok().getLoc(), "'(' expected");
2815 return MatchOperand_ParseFail;
2818 Parser.Lex(); // Eat the '(' token.
2821 Res = parseAnyRegister(Operands);
2822 if (Res != MatchOperand_Success)
2825 if (Parser.getTok().isNot(AsmToken::RParen)) {
2826 Error(Parser.getTok().getLoc(), "')' expected");
2827 return MatchOperand_ParseFail;
2830 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2832 Parser.Lex(); // Eat the ')' token.
2835 IdVal = MCConstantExpr::create(0, getContext());
2837 // Replace the register operand with the memory operand.
2838 std::unique_ptr<MipsOperand> op(
2839 static_cast<MipsOperand *>(Operands.back().release()));
2840 // Remove the register from the operands.
2841 // "op" will be managed by k_Memory.
2842 Operands.pop_back();
2843 // Add the memory operand.
2844 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2846 if (IdVal->evaluateAsAbsolute(Imm))
2847 IdVal = MCConstantExpr::create(Imm, getContext());
2848 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2849 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2853 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2854 return MatchOperand_Success;
2857 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2858 MCAsmParser &Parser = getParser();
2859 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
2861 SMLoc S = Parser.getTok().getLoc();
2863 if (Sym->isVariable())
2864 Expr = Sym->getVariableValue();
2867 if (Expr->getKind() == MCExpr::SymbolRef) {
2868 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2869 StringRef DefSymbol = Ref->getSymbol().getName();
2870 if (DefSymbol.startswith("$")) {
2871 OperandMatchResultTy ResTy =
2872 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2873 if (ResTy == MatchOperand_Success) {
2876 } else if (ResTy == MatchOperand_ParseFail)
2877 llvm_unreachable("Should never ParseFail");
2880 } else if (Expr->getKind() == MCExpr::Constant) {
2882 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2884 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2891 MipsAsmParser::OperandMatchResultTy
2892 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2893 StringRef Identifier,
2895 int Index = matchCPURegisterName(Identifier);
2897 Operands.push_back(MipsOperand::createGPRReg(
2898 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2899 return MatchOperand_Success;
2902 Index = matchHWRegsRegisterName(Identifier);
2904 Operands.push_back(MipsOperand::createHWRegsReg(
2905 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2906 return MatchOperand_Success;
2909 Index = matchFPURegisterName(Identifier);
2911 Operands.push_back(MipsOperand::createFGRReg(
2912 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2913 return MatchOperand_Success;
2916 Index = matchFCCRegisterName(Identifier);
2918 Operands.push_back(MipsOperand::createFCCReg(
2919 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2920 return MatchOperand_Success;
2923 Index = matchACRegisterName(Identifier);
2925 Operands.push_back(MipsOperand::createACCReg(
2926 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2927 return MatchOperand_Success;
2930 Index = matchMSA128RegisterName(Identifier);
2932 Operands.push_back(MipsOperand::createMSA128Reg(
2933 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2934 return MatchOperand_Success;
2937 Index = matchMSA128CtrlRegisterName(Identifier);
2939 Operands.push_back(MipsOperand::createMSACtrlReg(
2940 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2941 return MatchOperand_Success;
2944 return MatchOperand_NoMatch;
2947 MipsAsmParser::OperandMatchResultTy
2948 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2949 MCAsmParser &Parser = getParser();
2950 auto Token = Parser.getLexer().peekTok(false);
2952 if (Token.is(AsmToken::Identifier)) {
2953 DEBUG(dbgs() << ".. identifier\n");
2954 StringRef Identifier = Token.getIdentifier();
2955 OperandMatchResultTy ResTy =
2956 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2958 } else if (Token.is(AsmToken::Integer)) {
2959 DEBUG(dbgs() << ".. integer\n");
2960 Operands.push_back(MipsOperand::createNumericReg(
2961 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2963 return MatchOperand_Success;
2966 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2968 return MatchOperand_NoMatch;
2971 MipsAsmParser::OperandMatchResultTy
2972 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2973 MCAsmParser &Parser = getParser();
2974 DEBUG(dbgs() << "parseAnyRegister\n");
2976 auto Token = Parser.getTok();
2978 SMLoc S = Token.getLoc();
2980 if (Token.isNot(AsmToken::Dollar)) {
2981 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2982 if (Token.is(AsmToken::Identifier)) {
2983 if (searchSymbolAlias(Operands))
2984 return MatchOperand_Success;
2986 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2987 return MatchOperand_NoMatch;
2989 DEBUG(dbgs() << ".. $\n");
2991 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2992 if (ResTy == MatchOperand_Success) {
2994 Parser.Lex(); // identifier
2999 MipsAsmParser::OperandMatchResultTy
3000 MipsAsmParser::parseImm(OperandVector &Operands) {
3001 MCAsmParser &Parser = getParser();
3002 switch (getLexer().getKind()) {
3004 return MatchOperand_NoMatch;
3005 case AsmToken::LParen:
3006 case AsmToken::Minus:
3007 case AsmToken::Plus:
3008 case AsmToken::Integer:
3009 case AsmToken::Tilde:
3010 case AsmToken::String:
3014 const MCExpr *IdVal;
3015 SMLoc S = Parser.getTok().getLoc();
3016 if (getParser().parseExpression(IdVal))
3017 return MatchOperand_ParseFail;
3019 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3020 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3021 return MatchOperand_Success;
3024 MipsAsmParser::OperandMatchResultTy
3025 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3026 MCAsmParser &Parser = getParser();
3027 DEBUG(dbgs() << "parseJumpTarget\n");
3029 SMLoc S = getLexer().getLoc();
3031 // Integers and expressions are acceptable
3032 OperandMatchResultTy ResTy = parseImm(Operands);
3033 if (ResTy != MatchOperand_NoMatch)
3036 // Registers are a valid target and have priority over symbols.
3037 ResTy = parseAnyRegister(Operands);
3038 if (ResTy != MatchOperand_NoMatch)
3041 const MCExpr *Expr = nullptr;
3042 if (Parser.parseExpression(Expr)) {
3043 // We have no way of knowing if a symbol was consumed so we must ParseFail
3044 return MatchOperand_ParseFail;
3047 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3048 return MatchOperand_Success;
3051 MipsAsmParser::OperandMatchResultTy
3052 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3053 MCAsmParser &Parser = getParser();
3054 const MCExpr *IdVal;
3055 // If the first token is '$' we may have register operand.
3056 if (Parser.getTok().is(AsmToken::Dollar))
3057 return MatchOperand_NoMatch;
3058 SMLoc S = Parser.getTok().getLoc();
3059 if (getParser().parseExpression(IdVal))
3060 return MatchOperand_ParseFail;
3061 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3062 assert(MCE && "Unexpected MCExpr type.");
3063 int64_t Val = MCE->getValue();
3064 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3065 Operands.push_back(MipsOperand::CreateImm(
3066 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3067 return MatchOperand_Success;
3070 MipsAsmParser::OperandMatchResultTy
3071 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3072 MCAsmParser &Parser = getParser();
3073 switch (getLexer().getKind()) {
3075 return MatchOperand_NoMatch;
3076 case AsmToken::LParen:
3077 case AsmToken::Plus:
3078 case AsmToken::Minus:
3079 case AsmToken::Integer:
3084 SMLoc S = Parser.getTok().getLoc();
3086 if (getParser().parseExpression(Expr))
3087 return MatchOperand_ParseFail;
3090 if (!Expr->evaluateAsAbsolute(Val)) {
3091 Error(S, "expected immediate value");
3092 return MatchOperand_ParseFail;
3095 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3096 // and because the CPU always adds one to the immediate field, the allowed
3097 // range becomes 1..4. We'll only check the range here and will deal
3098 // with the addition/subtraction when actually decoding/encoding
3100 if (Val < 1 || Val > 4) {
3101 Error(S, "immediate not in range (1..4)");
3102 return MatchOperand_ParseFail;
3106 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3107 return MatchOperand_Success;
3110 MipsAsmParser::OperandMatchResultTy
3111 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3112 MCAsmParser &Parser = getParser();
3113 SmallVector<unsigned, 10> Regs;
3115 unsigned PrevReg = Mips::NoRegister;
3116 bool RegRange = false;
3117 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3119 if (Parser.getTok().isNot(AsmToken::Dollar))
3120 return MatchOperand_ParseFail;
3122 SMLoc S = Parser.getTok().getLoc();
3123 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3124 SMLoc E = getLexer().getLoc();
3125 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3126 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3128 // Remove last register operand because registers from register range
3129 // should be inserted first.
3130 if (RegNo == Mips::RA) {
3131 Regs.push_back(RegNo);
3133 unsigned TmpReg = PrevReg + 1;
3134 while (TmpReg <= RegNo) {
3135 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3136 Error(E, "invalid register operand");
3137 return MatchOperand_ParseFail;
3141 Regs.push_back(TmpReg++);
3147 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3148 (RegNo != Mips::RA)) {
3149 Error(E, "$16 or $31 expected");
3150 return MatchOperand_ParseFail;
3151 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3152 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3153 Error(E, "invalid register operand");
3154 return MatchOperand_ParseFail;
3155 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3156 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3157 Error(E, "consecutive register numbers expected");
3158 return MatchOperand_ParseFail;
3161 Regs.push_back(RegNo);
3164 if (Parser.getTok().is(AsmToken::Minus))
3167 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3168 !Parser.getTok().isNot(AsmToken::Comma)) {
3169 Error(E, "',' or '-' expected");
3170 return MatchOperand_ParseFail;
3173 Lex(); // Consume comma or minus
3174 if (Parser.getTok().isNot(AsmToken::Dollar))
3180 SMLoc E = Parser.getTok().getLoc();
3181 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3182 parseMemOperand(Operands);
3183 return MatchOperand_Success;
3186 MipsAsmParser::OperandMatchResultTy
3187 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3188 MCAsmParser &Parser = getParser();
3190 SMLoc S = Parser.getTok().getLoc();
3191 if (parseAnyRegister(Operands) != MatchOperand_Success)
3192 return MatchOperand_ParseFail;
3194 SMLoc E = Parser.getTok().getLoc();
3195 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3196 unsigned Reg = Op.getGPR32Reg();
3197 Operands.pop_back();
3198 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3199 return MatchOperand_Success;
3202 MipsAsmParser::OperandMatchResultTy
3203 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3204 MCAsmParser &Parser = getParser();
3205 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3206 SmallVector<unsigned, 10> Regs;
3208 if (Parser.getTok().isNot(AsmToken::Dollar))
3209 return MatchOperand_ParseFail;
3211 SMLoc S = Parser.getTok().getLoc();
3213 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3214 return MatchOperand_ParseFail;
3216 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3217 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3218 Regs.push_back(RegNo);
3220 SMLoc E = Parser.getTok().getLoc();
3221 if (Parser.getTok().isNot(AsmToken::Comma)) {
3222 Error(E, "',' expected");
3223 return MatchOperand_ParseFail;
3229 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3230 return MatchOperand_ParseFail;
3232 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3233 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3234 Regs.push_back(RegNo);
3236 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3238 return MatchOperand_Success;
3241 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3243 MCSymbolRefExpr::VariantKind VK =
3244 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3245 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3246 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3247 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3248 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3249 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3250 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3251 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3252 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3253 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3254 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3255 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3256 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3257 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3258 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3259 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3260 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3261 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3262 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3263 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3264 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3265 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3266 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3267 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3268 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3269 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3270 .Default(MCSymbolRefExpr::VK_None);
3272 assert(VK != MCSymbolRefExpr::VK_None);
3277 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3279 /// ::= '(', register, ')'
3280 /// handle it before we iterate so we don't get tripped up by the lack of
3282 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3283 MCAsmParser &Parser = getParser();
3284 if (getLexer().is(AsmToken::LParen)) {
3286 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3288 if (parseOperand(Operands, Name)) {
3289 SMLoc Loc = getLexer().getLoc();
3290 Parser.eatToEndOfStatement();
3291 return Error(Loc, "unexpected token in argument list");
3293 if (Parser.getTok().isNot(AsmToken::RParen)) {
3294 SMLoc Loc = getLexer().getLoc();
3295 Parser.eatToEndOfStatement();
3296 return Error(Loc, "unexpected token, expected ')'");
3299 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3305 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3306 /// either one of these.
3307 /// ::= '[', register, ']'
3308 /// ::= '[', integer, ']'
3309 /// handle it before we iterate so we don't get tripped up by the lack of
3311 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3312 OperandVector &Operands) {
3313 MCAsmParser &Parser = getParser();
3314 if (getLexer().is(AsmToken::LBrac)) {
3316 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3318 if (parseOperand(Operands, Name)) {
3319 SMLoc Loc = getLexer().getLoc();
3320 Parser.eatToEndOfStatement();
3321 return Error(Loc, "unexpected token in argument list");
3323 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3324 SMLoc Loc = getLexer().getLoc();
3325 Parser.eatToEndOfStatement();
3326 return Error(Loc, "unexpected token, expected ']'");
3329 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3335 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3336 SMLoc NameLoc, OperandVector &Operands) {
3337 MCAsmParser &Parser = getParser();
3338 DEBUG(dbgs() << "ParseInstruction\n");
3340 // We have reached first instruction, module directive are now forbidden.
3341 getTargetStreamer().forbidModuleDirective();
3343 // Check if we have valid mnemonic
3344 if (!mnemonicIsValid(Name, 0)) {
3345 Parser.eatToEndOfStatement();
3346 return Error(NameLoc, "unknown instruction");
3348 // First operand in MCInst is instruction mnemonic.
3349 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3351 // Read the remaining operands.
3352 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3353 // Read the first operand.
3354 if (parseOperand(Operands, Name)) {
3355 SMLoc Loc = getLexer().getLoc();
3356 Parser.eatToEndOfStatement();
3357 return Error(Loc, "unexpected token in argument list");
3359 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3361 // AFAIK, parenthesis suffixes are never on the first operand
3363 while (getLexer().is(AsmToken::Comma)) {
3364 Parser.Lex(); // Eat the comma.
3365 // Parse and remember the operand.
3366 if (parseOperand(Operands, Name)) {
3367 SMLoc Loc = getLexer().getLoc();
3368 Parser.eatToEndOfStatement();
3369 return Error(Loc, "unexpected token in argument list");
3371 // Parse bracket and parenthesis suffixes before we iterate
3372 if (getLexer().is(AsmToken::LBrac)) {
3373 if (parseBracketSuffix(Name, Operands))
3375 } else if (getLexer().is(AsmToken::LParen) &&
3376 parseParenSuffix(Name, Operands))
3380 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3381 SMLoc Loc = getLexer().getLoc();
3382 Parser.eatToEndOfStatement();
3383 return Error(Loc, "unexpected token in argument list");
3385 Parser.Lex(); // Consume the EndOfStatement.
3389 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3390 MCAsmParser &Parser = getParser();
3391 SMLoc Loc = getLexer().getLoc();
3392 Parser.eatToEndOfStatement();
3393 return Error(Loc, ErrorMsg);
3396 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3397 return Error(Loc, ErrorMsg);
3400 bool MipsAsmParser::parseSetNoAtDirective() {
3401 MCAsmParser &Parser = getParser();
3402 // Line should look like: ".set noat".
3404 // Set the $at register to $0.
3405 AssemblerOptions.back()->setATRegIndex(0);
3407 Parser.Lex(); // Eat "noat".
3409 // If this is not the end of the statement, report an error.
3410 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3411 reportParseError("unexpected token, expected end of statement");
3415 getTargetStreamer().emitDirectiveSetNoAt();
3416 Parser.Lex(); // Consume the EndOfStatement.
3420 bool MipsAsmParser::parseSetAtDirective() {
3421 // Line can be: ".set at", which sets $at to $1
3422 // or ".set at=$reg", which sets $at to $reg.
3423 MCAsmParser &Parser = getParser();
3424 Parser.Lex(); // Eat "at".
3426 if (getLexer().is(AsmToken::EndOfStatement)) {
3427 // No register was specified, so we set $at to $1.
3428 AssemblerOptions.back()->setATRegIndex(1);
3430 getTargetStreamer().emitDirectiveSetAt();
3431 Parser.Lex(); // Consume the EndOfStatement.
3435 if (getLexer().isNot(AsmToken::Equal)) {
3436 reportParseError("unexpected token, expected equals sign");
3439 Parser.Lex(); // Eat "=".
3441 if (getLexer().isNot(AsmToken::Dollar)) {
3442 if (getLexer().is(AsmToken::EndOfStatement)) {
3443 reportParseError("no register specified");
3446 reportParseError("unexpected token, expected dollar sign '$'");
3450 Parser.Lex(); // Eat "$".
3452 // Find out what "reg" is.
3454 const AsmToken &Reg = Parser.getTok();
3455 if (Reg.is(AsmToken::Identifier)) {
3456 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3457 } else if (Reg.is(AsmToken::Integer)) {
3458 AtRegNo = Reg.getIntVal();
3460 reportParseError("unexpected token, expected identifier or integer");
3464 // Check if $reg is a valid register. If it is, set $at to $reg.
3465 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3466 reportParseError("invalid register");
3469 Parser.Lex(); // Eat "reg".
3471 // If this is not the end of the statement, report an error.
3472 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3473 reportParseError("unexpected token, expected end of statement");
3477 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3479 Parser.Lex(); // Consume the EndOfStatement.
3483 bool MipsAsmParser::parseSetReorderDirective() {
3484 MCAsmParser &Parser = getParser();
3486 // If this is not the end of the statement, report an error.
3487 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3488 reportParseError("unexpected token, expected end of statement");
3491 AssemblerOptions.back()->setReorder();
3492 getTargetStreamer().emitDirectiveSetReorder();
3493 Parser.Lex(); // Consume the EndOfStatement.
3497 bool MipsAsmParser::parseSetNoReorderDirective() {
3498 MCAsmParser &Parser = getParser();
3500 // If this is not the end of the statement, report an error.
3501 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3502 reportParseError("unexpected token, expected end of statement");
3505 AssemblerOptions.back()->setNoReorder();
3506 getTargetStreamer().emitDirectiveSetNoReorder();
3507 Parser.Lex(); // Consume the EndOfStatement.
3511 bool MipsAsmParser::parseSetMacroDirective() {
3512 MCAsmParser &Parser = getParser();
3514 // If this is not the end of the statement, report an error.
3515 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3516 reportParseError("unexpected token, expected end of statement");
3519 AssemblerOptions.back()->setMacro();
3520 getTargetStreamer().emitDirectiveSetMacro();
3521 Parser.Lex(); // Consume the EndOfStatement.
3525 bool MipsAsmParser::parseSetNoMacroDirective() {
3526 MCAsmParser &Parser = getParser();
3528 // If this is not the end of the statement, report an error.
3529 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3530 reportParseError("unexpected token, expected end of statement");
3533 if (AssemblerOptions.back()->isReorder()) {
3534 reportParseError("`noreorder' must be set before `nomacro'");
3537 AssemblerOptions.back()->setNoMacro();
3538 getTargetStreamer().emitDirectiveSetNoMacro();
3539 Parser.Lex(); // Consume the EndOfStatement.
3543 bool MipsAsmParser::parseSetMsaDirective() {
3544 MCAsmParser &Parser = getParser();
3547 // If this is not the end of the statement, report an error.
3548 if (getLexer().isNot(AsmToken::EndOfStatement))
3549 return reportParseError("unexpected token, expected end of statement");
3551 setFeatureBits(Mips::FeatureMSA, "msa");
3552 getTargetStreamer().emitDirectiveSetMsa();
3556 bool MipsAsmParser::parseSetNoMsaDirective() {
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 clearFeatureBits(Mips::FeatureMSA, "msa");
3565 getTargetStreamer().emitDirectiveSetNoMsa();
3569 bool MipsAsmParser::parseSetNoDspDirective() {
3570 MCAsmParser &Parser = getParser();
3571 Parser.Lex(); // Eat "nodsp".
3573 // If this is not the end of the statement, report an error.
3574 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3575 reportParseError("unexpected token, expected end of statement");
3579 clearFeatureBits(Mips::FeatureDSP, "dsp");
3580 getTargetStreamer().emitDirectiveSetNoDsp();
3584 bool MipsAsmParser::parseSetMips16Directive() {
3585 MCAsmParser &Parser = getParser();
3586 Parser.Lex(); // Eat "mips16".
3588 // If this is not the end of the statement, report an error.
3589 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3590 reportParseError("unexpected token, expected end of statement");
3594 setFeatureBits(Mips::FeatureMips16, "mips16");
3595 getTargetStreamer().emitDirectiveSetMips16();
3596 Parser.Lex(); // Consume the EndOfStatement.
3600 bool MipsAsmParser::parseSetNoMips16Directive() {
3601 MCAsmParser &Parser = getParser();
3602 Parser.Lex(); // Eat "nomips16".
3604 // If this is not the end of the statement, report an error.
3605 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3606 reportParseError("unexpected token, expected end of statement");
3610 clearFeatureBits(Mips::FeatureMips16, "mips16");
3611 getTargetStreamer().emitDirectiveSetNoMips16();
3612 Parser.Lex(); // Consume the EndOfStatement.
3616 bool MipsAsmParser::parseSetFpDirective() {
3617 MCAsmParser &Parser = getParser();
3618 MipsABIFlagsSection::FpABIKind FpAbiVal;
3619 // Line can be: .set fp=32
3622 Parser.Lex(); // Eat fp token
3623 AsmToken Tok = Parser.getTok();
3624 if (Tok.isNot(AsmToken::Equal)) {
3625 reportParseError("unexpected token, expected equals sign '='");
3628 Parser.Lex(); // Eat '=' token.
3629 Tok = Parser.getTok();
3631 if (!parseFpABIValue(FpAbiVal, ".set"))
3634 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3635 reportParseError("unexpected token, expected end of statement");
3638 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3639 Parser.Lex(); // Consume the EndOfStatement.
3643 bool MipsAsmParser::parseSetPopDirective() {
3644 MCAsmParser &Parser = getParser();
3645 SMLoc Loc = getLexer().getLoc();
3648 if (getLexer().isNot(AsmToken::EndOfStatement))
3649 return reportParseError("unexpected token, expected end of statement");
3651 // Always keep an element on the options "stack" to prevent the user
3652 // from changing the initial options. This is how we remember them.
3653 if (AssemblerOptions.size() == 2)
3654 return reportParseError(Loc, ".set pop with no .set push");
3656 AssemblerOptions.pop_back();
3657 setAvailableFeatures(
3658 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
3659 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
3661 getTargetStreamer().emitDirectiveSetPop();
3665 bool MipsAsmParser::parseSetPushDirective() {
3666 MCAsmParser &Parser = getParser();
3668 if (getLexer().isNot(AsmToken::EndOfStatement))
3669 return reportParseError("unexpected token, expected end of statement");
3671 // Create a copy of the current assembler options environment and push it.
3672 AssemblerOptions.push_back(
3673 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3675 getTargetStreamer().emitDirectiveSetPush();
3679 bool MipsAsmParser::parseSetSoftFloatDirective() {
3680 MCAsmParser &Parser = getParser();
3682 if (getLexer().isNot(AsmToken::EndOfStatement))
3683 return reportParseError("unexpected token, expected end of statement");
3685 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3686 getTargetStreamer().emitDirectiveSetSoftFloat();
3690 bool MipsAsmParser::parseSetHardFloatDirective() {
3691 MCAsmParser &Parser = getParser();
3693 if (getLexer().isNot(AsmToken::EndOfStatement))
3694 return reportParseError("unexpected token, expected end of statement");
3696 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3697 getTargetStreamer().emitDirectiveSetHardFloat();
3701 bool MipsAsmParser::parseSetAssignment() {
3703 const MCExpr *Value;
3704 MCAsmParser &Parser = getParser();
3706 if (Parser.parseIdentifier(Name))
3707 reportParseError("expected identifier after .set");
3709 if (getLexer().isNot(AsmToken::Comma))
3710 return reportParseError("unexpected token, expected comma");
3713 if (Parser.parseExpression(Value))
3714 return reportParseError("expected valid expression after comma");
3716 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3717 Sym->setVariableValue(Value);
3722 bool MipsAsmParser::parseSetMips0Directive() {
3723 MCAsmParser &Parser = getParser();
3725 if (getLexer().isNot(AsmToken::EndOfStatement))
3726 return reportParseError("unexpected token, expected end of statement");
3728 // Reset assembler options to their initial values.
3729 setAvailableFeatures(
3730 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
3731 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
3732 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3734 getTargetStreamer().emitDirectiveSetMips0();
3738 bool MipsAsmParser::parseSetArchDirective() {
3739 MCAsmParser &Parser = getParser();
3741 if (getLexer().isNot(AsmToken::Equal))
3742 return reportParseError("unexpected token, expected equals sign");
3746 if (Parser.parseIdentifier(Arch))
3747 return reportParseError("expected arch identifier");
3749 StringRef ArchFeatureName =
3750 StringSwitch<StringRef>(Arch)
3751 .Case("mips1", "mips1")
3752 .Case("mips2", "mips2")
3753 .Case("mips3", "mips3")
3754 .Case("mips4", "mips4")
3755 .Case("mips5", "mips5")
3756 .Case("mips32", "mips32")
3757 .Case("mips32r2", "mips32r2")
3758 .Case("mips32r3", "mips32r3")
3759 .Case("mips32r5", "mips32r5")
3760 .Case("mips32r6", "mips32r6")
3761 .Case("mips64", "mips64")
3762 .Case("mips64r2", "mips64r2")
3763 .Case("mips64r3", "mips64r3")
3764 .Case("mips64r5", "mips64r5")
3765 .Case("mips64r6", "mips64r6")
3766 .Case("cnmips", "cnmips")
3767 .Case("r4000", "mips3") // This is an implementation of Mips3.
3770 if (ArchFeatureName.empty())
3771 return reportParseError("unsupported architecture");
3773 selectArch(ArchFeatureName);
3774 getTargetStreamer().emitDirectiveSetArch(Arch);
3778 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3779 MCAsmParser &Parser = getParser();
3781 if (getLexer().isNot(AsmToken::EndOfStatement))
3782 return reportParseError("unexpected token, expected end of statement");
3786 llvm_unreachable("Unimplemented feature");
3787 case Mips::FeatureDSP:
3788 setFeatureBits(Mips::FeatureDSP, "dsp");
3789 getTargetStreamer().emitDirectiveSetDsp();
3791 case Mips::FeatureMicroMips:
3792 getTargetStreamer().emitDirectiveSetMicroMips();
3794 case Mips::FeatureMips1:
3795 selectArch("mips1");
3796 getTargetStreamer().emitDirectiveSetMips1();
3798 case Mips::FeatureMips2:
3799 selectArch("mips2");
3800 getTargetStreamer().emitDirectiveSetMips2();
3802 case Mips::FeatureMips3:
3803 selectArch("mips3");
3804 getTargetStreamer().emitDirectiveSetMips3();
3806 case Mips::FeatureMips4:
3807 selectArch("mips4");
3808 getTargetStreamer().emitDirectiveSetMips4();
3810 case Mips::FeatureMips5:
3811 selectArch("mips5");
3812 getTargetStreamer().emitDirectiveSetMips5();
3814 case Mips::FeatureMips32:
3815 selectArch("mips32");
3816 getTargetStreamer().emitDirectiveSetMips32();
3818 case Mips::FeatureMips32r2:
3819 selectArch("mips32r2");
3820 getTargetStreamer().emitDirectiveSetMips32R2();
3822 case Mips::FeatureMips32r3:
3823 selectArch("mips32r3");
3824 getTargetStreamer().emitDirectiveSetMips32R3();
3826 case Mips::FeatureMips32r5:
3827 selectArch("mips32r5");
3828 getTargetStreamer().emitDirectiveSetMips32R5();
3830 case Mips::FeatureMips32r6:
3831 selectArch("mips32r6");
3832 getTargetStreamer().emitDirectiveSetMips32R6();
3834 case Mips::FeatureMips64:
3835 selectArch("mips64");
3836 getTargetStreamer().emitDirectiveSetMips64();
3838 case Mips::FeatureMips64r2:
3839 selectArch("mips64r2");
3840 getTargetStreamer().emitDirectiveSetMips64R2();
3842 case Mips::FeatureMips64r3:
3843 selectArch("mips64r3");
3844 getTargetStreamer().emitDirectiveSetMips64R3();
3846 case Mips::FeatureMips64r5:
3847 selectArch("mips64r5");
3848 getTargetStreamer().emitDirectiveSetMips64R5();
3850 case Mips::FeatureMips64r6:
3851 selectArch("mips64r6");
3852 getTargetStreamer().emitDirectiveSetMips64R6();
3858 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3859 MCAsmParser &Parser = getParser();
3860 if (getLexer().isNot(AsmToken::Comma)) {
3861 SMLoc Loc = getLexer().getLoc();
3862 Parser.eatToEndOfStatement();
3863 return Error(Loc, ErrorStr);
3866 Parser.Lex(); // Eat the comma.
3870 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3871 if (AssemblerOptions.back()->isReorder())
3872 Warning(Loc, ".cpload should be inside a noreorder section");
3874 if (inMips16Mode()) {
3875 reportParseError(".cpload is not supported in Mips16 mode");
3879 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3880 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3881 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3882 reportParseError("expected register containing function address");
3886 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3887 if (!RegOpnd.isGPRAsmReg()) {
3888 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3892 // If this is not the end of the statement, report an error.
3893 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3894 reportParseError("unexpected token, expected end of statement");
3898 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3902 bool MipsAsmParser::parseDirectiveCPSetup() {
3903 MCAsmParser &Parser = getParser();
3906 bool SaveIsReg = true;
3908 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3909 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3910 if (ResTy == MatchOperand_NoMatch) {
3911 reportParseError("expected register containing function address");
3912 Parser.eatToEndOfStatement();
3916 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3917 if (!FuncRegOpnd.isGPRAsmReg()) {
3918 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3919 Parser.eatToEndOfStatement();
3923 FuncReg = FuncRegOpnd.getGPR32Reg();
3926 if (!eatComma("unexpected token, expected comma"))
3929 ResTy = parseAnyRegister(TmpReg);
3930 if (ResTy == MatchOperand_NoMatch) {
3931 const AsmToken &Tok = Parser.getTok();
3932 if (Tok.is(AsmToken::Integer)) {
3933 Save = Tok.getIntVal();
3937 reportParseError("expected save register or stack offset");
3938 Parser.eatToEndOfStatement();
3942 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3943 if (!SaveOpnd.isGPRAsmReg()) {
3944 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3945 Parser.eatToEndOfStatement();
3948 Save = SaveOpnd.getGPR32Reg();
3951 if (!eatComma("unexpected token, expected comma"))
3955 if (Parser.parseExpression(Expr)) {
3956 reportParseError("expected expression");
3960 if (Expr->getKind() != MCExpr::SymbolRef) {
3961 reportParseError("expected symbol");
3964 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3966 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3971 bool MipsAsmParser::parseDirectiveNaN() {
3972 MCAsmParser &Parser = getParser();
3973 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3974 const AsmToken &Tok = Parser.getTok();
3976 if (Tok.getString() == "2008") {
3978 getTargetStreamer().emitDirectiveNaN2008();
3980 } else if (Tok.getString() == "legacy") {
3982 getTargetStreamer().emitDirectiveNaNLegacy();
3986 // If we don't recognize the option passed to the .nan
3987 // directive (e.g. no option or unknown option), emit an error.
3988 reportParseError("invalid option in .nan directive");
3992 bool MipsAsmParser::parseDirectiveSet() {
3993 MCAsmParser &Parser = getParser();
3994 // Get the next token.
3995 const AsmToken &Tok = Parser.getTok();
3997 if (Tok.getString() == "noat") {
3998 return parseSetNoAtDirective();
3999 } else if (Tok.getString() == "at") {
4000 return parseSetAtDirective();
4001 } else if (Tok.getString() == "arch") {
4002 return parseSetArchDirective();
4003 } else if (Tok.getString() == "fp") {
4004 return parseSetFpDirective();
4005 } else if (Tok.getString() == "pop") {
4006 return parseSetPopDirective();
4007 } else if (Tok.getString() == "push") {
4008 return parseSetPushDirective();
4009 } else if (Tok.getString() == "reorder") {
4010 return parseSetReorderDirective();
4011 } else if (Tok.getString() == "noreorder") {
4012 return parseSetNoReorderDirective();
4013 } else if (Tok.getString() == "macro") {
4014 return parseSetMacroDirective();
4015 } else if (Tok.getString() == "nomacro") {
4016 return parseSetNoMacroDirective();
4017 } else if (Tok.getString() == "mips16") {
4018 return parseSetMips16Directive();
4019 } else if (Tok.getString() == "nomips16") {
4020 return parseSetNoMips16Directive();
4021 } else if (Tok.getString() == "nomicromips") {
4022 getTargetStreamer().emitDirectiveSetNoMicroMips();
4023 Parser.eatToEndOfStatement();
4025 } else if (Tok.getString() == "micromips") {
4026 return parseSetFeature(Mips::FeatureMicroMips);
4027 } else if (Tok.getString() == "mips0") {
4028 return parseSetMips0Directive();
4029 } else if (Tok.getString() == "mips1") {
4030 return parseSetFeature(Mips::FeatureMips1);
4031 } else if (Tok.getString() == "mips2") {
4032 return parseSetFeature(Mips::FeatureMips2);
4033 } else if (Tok.getString() == "mips3") {
4034 return parseSetFeature(Mips::FeatureMips3);
4035 } else if (Tok.getString() == "mips4") {
4036 return parseSetFeature(Mips::FeatureMips4);
4037 } else if (Tok.getString() == "mips5") {
4038 return parseSetFeature(Mips::FeatureMips5);
4039 } else if (Tok.getString() == "mips32") {
4040 return parseSetFeature(Mips::FeatureMips32);
4041 } else if (Tok.getString() == "mips32r2") {
4042 return parseSetFeature(Mips::FeatureMips32r2);
4043 } else if (Tok.getString() == "mips32r3") {
4044 return parseSetFeature(Mips::FeatureMips32r3);
4045 } else if (Tok.getString() == "mips32r5") {
4046 return parseSetFeature(Mips::FeatureMips32r5);
4047 } else if (Tok.getString() == "mips32r6") {
4048 return parseSetFeature(Mips::FeatureMips32r6);
4049 } else if (Tok.getString() == "mips64") {
4050 return parseSetFeature(Mips::FeatureMips64);
4051 } else if (Tok.getString() == "mips64r2") {
4052 return parseSetFeature(Mips::FeatureMips64r2);
4053 } else if (Tok.getString() == "mips64r3") {
4054 return parseSetFeature(Mips::FeatureMips64r3);
4055 } else if (Tok.getString() == "mips64r5") {
4056 return parseSetFeature(Mips::FeatureMips64r5);
4057 } else if (Tok.getString() == "mips64r6") {
4058 return parseSetFeature(Mips::FeatureMips64r6);
4059 } else if (Tok.getString() == "dsp") {
4060 return parseSetFeature(Mips::FeatureDSP);
4061 } else if (Tok.getString() == "nodsp") {
4062 return parseSetNoDspDirective();
4063 } else if (Tok.getString() == "msa") {
4064 return parseSetMsaDirective();
4065 } else if (Tok.getString() == "nomsa") {
4066 return parseSetNoMsaDirective();
4067 } else if (Tok.getString() == "softfloat") {
4068 return parseSetSoftFloatDirective();
4069 } else if (Tok.getString() == "hardfloat") {
4070 return parseSetHardFloatDirective();
4072 // It is just an identifier, look for an assignment.
4073 parseSetAssignment();
4080 /// parseDataDirective
4081 /// ::= .word [ expression (, expression)* ]
4082 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4083 MCAsmParser &Parser = getParser();
4084 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4086 const MCExpr *Value;
4087 if (getParser().parseExpression(Value))
4090 getParser().getStreamer().EmitValue(Value, Size);
4092 if (getLexer().is(AsmToken::EndOfStatement))
4095 if (getLexer().isNot(AsmToken::Comma))
4096 return Error(L, "unexpected token, expected comma");
4105 /// parseDirectiveGpWord
4106 /// ::= .gpword local_sym
4107 bool MipsAsmParser::parseDirectiveGpWord() {
4108 MCAsmParser &Parser = getParser();
4109 const MCExpr *Value;
4110 // EmitGPRel32Value requires an expression, so we are using base class
4111 // method to evaluate the expression.
4112 if (getParser().parseExpression(Value))
4114 getParser().getStreamer().EmitGPRel32Value(Value);
4116 if (getLexer().isNot(AsmToken::EndOfStatement))
4117 return Error(getLexer().getLoc(),
4118 "unexpected token, expected end of statement");
4119 Parser.Lex(); // Eat EndOfStatement token.
4123 /// parseDirectiveGpDWord
4124 /// ::= .gpdword local_sym
4125 bool MipsAsmParser::parseDirectiveGpDWord() {
4126 MCAsmParser &Parser = getParser();
4127 const MCExpr *Value;
4128 // EmitGPRel64Value requires an expression, so we are using base class
4129 // method to evaluate the expression.
4130 if (getParser().parseExpression(Value))
4132 getParser().getStreamer().EmitGPRel64Value(Value);
4134 if (getLexer().isNot(AsmToken::EndOfStatement))
4135 return Error(getLexer().getLoc(),
4136 "unexpected token, expected end of statement");
4137 Parser.Lex(); // Eat EndOfStatement token.
4141 bool MipsAsmParser::parseDirectiveOption() {
4142 MCAsmParser &Parser = getParser();
4143 // Get the option token.
4144 AsmToken Tok = Parser.getTok();
4145 // At the moment only identifiers are supported.
4146 if (Tok.isNot(AsmToken::Identifier)) {
4147 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4148 Parser.eatToEndOfStatement();
4152 StringRef Option = Tok.getIdentifier();
4154 if (Option == "pic0") {
4155 getTargetStreamer().emitDirectiveOptionPic0();
4157 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4158 Error(Parser.getTok().getLoc(),
4159 "unexpected token, expected end of statement");
4160 Parser.eatToEndOfStatement();
4165 if (Option == "pic2") {
4166 getTargetStreamer().emitDirectiveOptionPic2();
4168 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4169 Error(Parser.getTok().getLoc(),
4170 "unexpected token, expected end of statement");
4171 Parser.eatToEndOfStatement();
4177 Warning(Parser.getTok().getLoc(),
4178 "unknown option, expected 'pic0' or 'pic2'");
4179 Parser.eatToEndOfStatement();
4183 /// parseInsnDirective
4185 bool MipsAsmParser::parseInsnDirective() {
4186 // If this is not the end of the statement, report an error.
4187 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4188 reportParseError("unexpected token, expected end of statement");
4192 // The actual label marking happens in
4193 // MipsELFStreamer::createPendingLabelRelocs().
4194 getTargetStreamer().emitDirectiveInsn();
4196 getParser().Lex(); // Eat EndOfStatement token.
4200 /// parseDirectiveModule
4201 /// ::= .module oddspreg
4202 /// ::= .module nooddspreg
4203 /// ::= .module fp=value
4204 bool MipsAsmParser::parseDirectiveModule() {
4205 MCAsmParser &Parser = getParser();
4206 MCAsmLexer &Lexer = getLexer();
4207 SMLoc L = Lexer.getLoc();
4209 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4210 // TODO : get a better message.
4211 reportParseError(".module directive must appear before any code");
4216 if (Parser.parseIdentifier(Option)) {
4217 reportParseError("expected .module option identifier");
4221 if (Option == "oddspreg") {
4222 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4223 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4225 // If this is not the end of the statement, report an error.
4226 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4227 reportParseError("unexpected token, expected end of statement");
4231 return false; // parseDirectiveModule has finished successfully.
4232 } else if (Option == "nooddspreg") {
4234 Error(L, "'.module nooddspreg' requires the O32 ABI");
4238 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4239 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4241 // If this is not the end of the statement, report an error.
4242 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4243 reportParseError("unexpected token, expected end of statement");
4247 return false; // parseDirectiveModule has finished successfully.
4248 } else if (Option == "fp") {
4249 return parseDirectiveModuleFP();
4251 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4255 /// parseDirectiveModuleFP
4259 bool MipsAsmParser::parseDirectiveModuleFP() {
4260 MCAsmParser &Parser = getParser();
4261 MCAsmLexer &Lexer = getLexer();
4263 if (Lexer.isNot(AsmToken::Equal)) {
4264 reportParseError("unexpected token, expected equals sign '='");
4267 Parser.Lex(); // Eat '=' token.
4269 MipsABIFlagsSection::FpABIKind FpABI;
4270 if (!parseFpABIValue(FpABI, ".module"))
4273 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4274 reportParseError("unexpected token, expected end of statement");
4278 // Emit appropriate flags.
4279 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4280 Parser.Lex(); // Consume the EndOfStatement.
4284 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4285 StringRef Directive) {
4286 MCAsmParser &Parser = getParser();
4287 MCAsmLexer &Lexer = getLexer();
4289 if (Lexer.is(AsmToken::Identifier)) {
4290 StringRef Value = Parser.getTok().getString();
4293 if (Value != "xx") {
4294 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4299 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4303 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4307 if (Lexer.is(AsmToken::Integer)) {
4308 unsigned Value = Parser.getTok().getIntVal();
4311 if (Value != 32 && Value != 64) {
4312 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4318 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4322 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4324 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4332 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4333 MCAsmParser &Parser = getParser();
4334 StringRef IDVal = DirectiveID.getString();
4336 if (IDVal == ".cpload")
4337 return parseDirectiveCpLoad(DirectiveID.getLoc());
4338 if (IDVal == ".dword") {
4339 parseDataDirective(8, DirectiveID.getLoc());
4342 if (IDVal == ".ent") {
4343 StringRef SymbolName;
4345 if (Parser.parseIdentifier(SymbolName)) {
4346 reportParseError("expected identifier after .ent");
4350 // There's an undocumented extension that allows an integer to
4351 // follow the name of the procedure which AFAICS is ignored by GAS.
4352 // Example: .ent foo,2
4353 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4354 if (getLexer().isNot(AsmToken::Comma)) {
4355 // Even though we accept this undocumented extension for compatibility
4356 // reasons, the additional integer argument does not actually change
4357 // the behaviour of the '.ent' directive, so we would like to discourage
4358 // its use. We do this by not referring to the extended version in
4359 // error messages which are not directly related to its use.
4360 reportParseError("unexpected token, expected end of statement");
4363 Parser.Lex(); // Eat the comma.
4364 const MCExpr *DummyNumber;
4365 int64_t DummyNumberVal;
4366 // If the user was explicitly trying to use the extended version,
4367 // we still give helpful extension-related error messages.
4368 if (Parser.parseExpression(DummyNumber)) {
4369 reportParseError("expected number after comma");
4372 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4373 reportParseError("expected an absolute expression after comma");
4378 // If this is not the end of the statement, report an error.
4379 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4380 reportParseError("unexpected token, expected end of statement");
4384 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4386 getTargetStreamer().emitDirectiveEnt(*Sym);
4391 if (IDVal == ".end") {
4392 StringRef SymbolName;
4394 if (Parser.parseIdentifier(SymbolName)) {
4395 reportParseError("expected identifier after .end");
4399 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4400 reportParseError("unexpected token, expected end of statement");
4404 if (CurrentFn == nullptr) {
4405 reportParseError(".end used without .ent");
4409 if ((SymbolName != CurrentFn->getName())) {
4410 reportParseError(".end symbol does not match .ent symbol");
4414 getTargetStreamer().emitDirectiveEnd(SymbolName);
4415 CurrentFn = nullptr;
4419 if (IDVal == ".frame") {
4420 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4421 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4422 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4423 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4424 reportParseError("expected stack register");
4428 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4429 if (!StackRegOpnd.isGPRAsmReg()) {
4430 reportParseError(StackRegOpnd.getStartLoc(),
4431 "expected general purpose register");
4434 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4436 if (Parser.getTok().is(AsmToken::Comma))
4439 reportParseError("unexpected token, expected comma");
4443 // Parse the frame size.
4444 const MCExpr *FrameSize;
4445 int64_t FrameSizeVal;
4447 if (Parser.parseExpression(FrameSize)) {
4448 reportParseError("expected frame size value");
4452 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4453 reportParseError("frame size not an absolute expression");
4457 if (Parser.getTok().is(AsmToken::Comma))
4460 reportParseError("unexpected token, expected comma");
4464 // Parse the return register.
4466 ResTy = parseAnyRegister(TmpReg);
4467 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4468 reportParseError("expected return register");
4472 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4473 if (!ReturnRegOpnd.isGPRAsmReg()) {
4474 reportParseError(ReturnRegOpnd.getStartLoc(),
4475 "expected general purpose register");
4479 // If this is not the end of the statement, report an error.
4480 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4481 reportParseError("unexpected token, expected end of statement");
4485 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4486 ReturnRegOpnd.getGPR32Reg());
4490 if (IDVal == ".set") {
4491 return parseDirectiveSet();
4494 if (IDVal == ".mask" || IDVal == ".fmask") {
4495 // .mask bitmask, frame_offset
4496 // bitmask: One bit for each register used.
4497 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4498 // first register is expected to be saved.
4500 // .mask 0x80000000, -4
4501 // .fmask 0x80000000, -4
4504 // Parse the bitmask
4505 const MCExpr *BitMask;
4508 if (Parser.parseExpression(BitMask)) {
4509 reportParseError("expected bitmask value");
4513 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4514 reportParseError("bitmask not an absolute expression");
4518 if (Parser.getTok().is(AsmToken::Comma))
4521 reportParseError("unexpected token, expected comma");
4525 // Parse the frame_offset
4526 const MCExpr *FrameOffset;
4527 int64_t FrameOffsetVal;
4529 if (Parser.parseExpression(FrameOffset)) {
4530 reportParseError("expected frame offset value");
4534 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4535 reportParseError("frame offset not an absolute expression");
4539 // If this is not the end of the statement, report an error.
4540 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4541 reportParseError("unexpected token, expected end of statement");
4545 if (IDVal == ".mask")
4546 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4548 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4552 if (IDVal == ".nan")
4553 return parseDirectiveNaN();
4555 if (IDVal == ".gpword") {
4556 parseDirectiveGpWord();
4560 if (IDVal == ".gpdword") {
4561 parseDirectiveGpDWord();
4565 if (IDVal == ".word") {
4566 parseDataDirective(4, DirectiveID.getLoc());
4570 if (IDVal == ".option")
4571 return parseDirectiveOption();
4573 if (IDVal == ".abicalls") {
4574 getTargetStreamer().emitDirectiveAbiCalls();
4575 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4576 Error(Parser.getTok().getLoc(),
4577 "unexpected token, expected end of statement");
4579 Parser.eatToEndOfStatement();
4584 if (IDVal == ".cpsetup")
4585 return parseDirectiveCPSetup();
4587 if (IDVal == ".module")
4588 return parseDirectiveModule();
4590 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4591 return parseInternalDirectiveReallowModule();
4593 if (IDVal == ".insn")
4594 return parseInsnDirective();
4599 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4600 // If this is not the end of the statement, report an error.
4601 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4602 reportParseError("unexpected token, expected end of statement");
4606 getTargetStreamer().reallowModuleDirective();
4608 getParser().Lex(); // Eat EndOfStatement token.
4612 extern "C" void LLVMInitializeMipsAsmParser() {
4613 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4614 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4615 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4616 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4619 #define GET_REGISTER_MATCHER
4620 #define GET_MATCHER_IMPLEMENTATION
4621 #include "MipsGenAsmMatcher.inc"