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(uint64_t 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 uint64_t getFeatures() const { return Features; }
74 void setFeatures(uint64_t 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;
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103 class MipsAsmParser : public MCTargetAsmParser {
104 MipsTargetStreamer &getTargetStreamer() {
105 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
106 return static_cast<MipsTargetStreamer &>(TS);
109 MCSubtargetInfo &STI;
111 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
112 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113 // nullptr, which indicates that no function is currently
114 // selected. This usually happens after an '.end func'
117 // Print a warning along with its fix-it message at the given range.
118 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
119 SMRange Range, bool ShowColors = true);
121 #define GET_ASSEMBLER_HEADER
122 #include "MipsGenAsmMatcher.inc"
124 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
126 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
127 OperandVector &Operands, MCStreamer &Out,
129 bool MatchingInlineAsm) override;
131 /// Parse a register as used in CFI directives
132 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
134 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
136 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
138 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
139 SMLoc NameLoc, OperandVector &Operands) override;
141 bool ParseDirective(AsmToken DirectiveID) override;
143 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy
146 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
147 StringRef Identifier, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy
150 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
152 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
154 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
156 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
158 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
160 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseRegisterPair (OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseMovePRegPair(OperandVector &Operands);
168 MipsAsmParser::OperandMatchResultTy
169 parseRegisterList (OperandVector &Operands);
171 bool searchSymbolAlias(OperandVector &Operands);
173 bool parseOperand(OperandVector &, StringRef Mnemonic);
175 bool needsExpansion(MCInst &Inst);
177 // Expands assembly pseudo instructions.
178 // Returns false on success, true otherwise.
179 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
186 bool Is32BitImm, SMLoc IDLoc,
187 SmallVectorImpl<MCInst> &Instructions);
189 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
195 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions);
197 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 void expandLoadAddressSym(const MCOperand &DstRegOp, const MCOperand &SymOp,
201 bool Is32BitSym, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions);
204 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
205 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
208 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
215 SmallVectorImpl<MCInst> &Instructions);
217 bool reportParseError(Twine ErrorMsg);
218 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
220 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
221 bool parseRelocOperand(const MCExpr *&Res);
223 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
225 bool isEvaluated(const MCExpr *Expr);
226 bool parseSetMips0Directive();
227 bool parseSetArchDirective();
228 bool parseSetFeature(uint64_t Feature);
229 bool parseDirectiveCpLoad(SMLoc Loc);
230 bool parseDirectiveCPSetup();
231 bool parseDirectiveNaN();
232 bool parseDirectiveSet();
233 bool parseDirectiveOption();
234 bool parseInsnDirective();
236 bool parseSetAtDirective();
237 bool parseSetNoAtDirective();
238 bool parseSetMacroDirective();
239 bool parseSetNoMacroDirective();
240 bool parseSetMsaDirective();
241 bool parseSetNoMsaDirective();
242 bool parseSetNoDspDirective();
243 bool parseSetReorderDirective();
244 bool parseSetNoReorderDirective();
245 bool parseSetMips16Directive();
246 bool parseSetNoMips16Directive();
247 bool parseSetFpDirective();
248 bool parseSetPopDirective();
249 bool parseSetPushDirective();
251 bool parseSetAssignment();
253 bool parseDataDirective(unsigned Size, SMLoc L);
254 bool parseDirectiveGpWord();
255 bool parseDirectiveGpDWord();
256 bool parseDirectiveModule();
257 bool parseDirectiveModuleFP();
258 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
259 StringRef Directive);
261 bool parseInternalDirectiveReallowModule();
263 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
265 bool eatComma(StringRef ErrorStr);
267 int matchCPURegisterName(StringRef Symbol);
269 int matchHWRegsRegisterName(StringRef Symbol);
271 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
273 int matchFPURegisterName(StringRef Name);
275 int matchFCCRegisterName(StringRef Name);
277 int matchACRegisterName(StringRef Name);
279 int matchMSA128RegisterName(StringRef Name);
281 int matchMSA128CtrlRegisterName(StringRef Name);
283 unsigned getReg(int RC, int RegNo);
285 unsigned getGPR(int RegNo);
287 /// Returns the internal register number for the current AT. Also checks if
288 /// the current AT is unavailable (set to $0) and gives an error if it is.
289 /// This should be used in pseudo-instruction expansions which need AT.
290 unsigned getATReg(SMLoc Loc);
292 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
293 SmallVectorImpl<MCInst> &Instructions);
295 // Helper function that checks if the value of a vector index is within the
296 // boundaries of accepted values for each RegisterKind
297 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
298 bool validateMSAIndex(int Val, int RegKind);
300 // Selects a new architecture by updating the FeatureBits with the necessary
301 // info including implied dependencies.
302 // Internally, it clears all the feature bits related to *any* architecture
303 // and selects the new one using the ToggleFeature functionality of the
304 // MCSubtargetInfo object that handles implied dependencies. The reason we
305 // clear all the arch related bits manually is because ToggleFeature only
306 // clears the features that imply the feature being cleared and not the
307 // features implied by the feature being cleared. This is easier to see
309 // --------------------------------------------------
310 // | Feature | Implies |
311 // | -------------------------------------------------|
312 // | FeatureMips1 | None |
313 // | FeatureMips2 | FeatureMips1 |
314 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
315 // | FeatureMips4 | FeatureMips3 |
317 // --------------------------------------------------
319 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
320 // FeatureMipsGP64 | FeatureMips1)
321 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
322 void selectArch(StringRef ArchFeature) {
323 FeatureBitset FeatureBits = STI.getFeatureBits();
324 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
325 STI.setFeatureBits(FeatureBits);
326 setAvailableFeatures(
327 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
328 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
331 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
332 if (!(STI.getFeatureBits()[Feature])) {
333 setAvailableFeatures(
334 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
336 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
339 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
340 if (STI.getFeatureBits()[Feature]) {
341 setAvailableFeatures(
342 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
344 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
348 enum MipsMatchResultTy {
349 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
350 #define GET_OPERAND_DIAGNOSTIC_TYPES
351 #include "MipsGenAsmMatcher.inc"
352 #undef GET_OPERAND_DIAGNOSTIC_TYPES
356 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
357 const MCInstrInfo &MII, const MCTargetOptions &Options)
358 : MCTargetAsmParser(), STI(sti),
359 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
360 sti.getCPU(), Options)) {
361 MCAsmParserExtension::Initialize(parser);
363 parser.addAliasForDirective(".asciiz", ".asciz");
365 // Initialize the set of available features.
366 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
368 // Remember the initial assembler options. The user can not modify these.
369 AssemblerOptions.push_back(
370 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
372 // Create an assembler options environment for the user to modify.
373 AssemblerOptions.push_back(
374 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
376 getTargetStreamer().updateABIInfo(*this);
378 if (!isABI_O32() && !useOddSPReg() != 0)
379 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
384 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
385 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
387 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
388 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
389 const MipsABIInfo &getABI() const { return ABI; }
390 bool isABI_N32() const { return ABI.IsN32(); }
391 bool isABI_N64() const { return ABI.IsN64(); }
392 bool isABI_O32() const { return ABI.IsO32(); }
393 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
395 bool useOddSPReg() const {
396 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
399 bool inMicroMipsMode() const {
400 return STI.getFeatureBits()[Mips::FeatureMicroMips];
402 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
403 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
404 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
405 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
406 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
407 bool hasMips32() const {
408 return STI.getFeatureBits()[Mips::FeatureMips32];
410 bool hasMips64() const {
411 return STI.getFeatureBits()[Mips::FeatureMips64];
413 bool hasMips32r2() const {
414 return STI.getFeatureBits()[Mips::FeatureMips32r2];
416 bool hasMips64r2() const {
417 return STI.getFeatureBits()[Mips::FeatureMips64r2];
419 bool hasMips32r3() const {
420 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
422 bool hasMips64r3() const {
423 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
425 bool hasMips32r5() const {
426 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
428 bool hasMips64r5() const {
429 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
431 bool hasMips32r6() const {
432 return STI.getFeatureBits()[Mips::FeatureMips32r6];
434 bool hasMips64r6() const {
435 return STI.getFeatureBits()[Mips::FeatureMips64r6];
438 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
439 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
440 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
441 bool hasCnMips() const {
442 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
445 bool inMips16Mode() const {
446 return STI.getFeatureBits()[Mips::FeatureMips16];
449 bool useSoftFloat() const {
450 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
453 /// Warn if RegIndex is the same as the current AT.
454 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
456 void warnIfNoMacro(SMLoc Loc);
462 /// MipsOperand - Instances of this class represent a parsed Mips machine
464 class MipsOperand : public MCParsedAsmOperand {
466 /// Broad categories of register classes
467 /// The exact class is finalized by the render method.
469 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
470 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
472 RegKind_FCC = 4, /// FCC
473 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
474 RegKind_MSACtrl = 16, /// MSA control registers
475 RegKind_COP2 = 32, /// COP2
476 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
478 RegKind_CCR = 128, /// CCR
479 RegKind_HWRegs = 256, /// HWRegs
480 RegKind_COP3 = 512, /// COP3
482 /// Potentially any (e.g. $1)
483 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
484 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
485 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
490 k_Immediate, /// An immediate (possibly involving symbol references)
491 k_Memory, /// Base + Offset Memory Address
492 k_PhysRegister, /// A physical register from the Mips namespace
493 k_RegisterIndex, /// A register index in one or more RegKind.
494 k_Token, /// A simple token
495 k_RegList, /// A physical register list
496 k_RegPair /// A pair of physical register
500 MipsOperand(KindTy K, MipsAsmParser &Parser)
501 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
504 /// For diagnostics, and checking the assembler temporary
505 MipsAsmParser &AsmParser;
513 unsigned Num; /// Register Number
517 unsigned Index; /// Index into the register class
518 RegKind Kind; /// Bitfield of the kinds it could possibly be
519 const MCRegisterInfo *RegInfo;
532 SmallVector<unsigned, 10> *List;
537 struct PhysRegOp PhysReg;
538 struct RegIdxOp RegIdx;
541 struct RegListOp RegList;
544 SMLoc StartLoc, EndLoc;
546 /// Internal constructor for register kinds
547 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
548 const MCRegisterInfo *RegInfo,
550 MipsAsmParser &Parser) {
551 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
552 Op->RegIdx.Index = Index;
553 Op->RegIdx.RegInfo = RegInfo;
554 Op->RegIdx.Kind = RegKind;
561 /// Coerce the register to GPR32 and return the real register for the current
563 unsigned getGPR32Reg() const {
564 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
565 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
566 unsigned ClassID = Mips::GPR32RegClassID;
567 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
570 /// Coerce the register to GPR32 and return the real register for the current
572 unsigned getGPRMM16Reg() const {
573 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
574 unsigned ClassID = Mips::GPR32RegClassID;
575 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
578 /// Coerce the register to GPR64 and return the real register for the current
580 unsigned getGPR64Reg() const {
581 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
582 unsigned ClassID = Mips::GPR64RegClassID;
583 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
587 /// Coerce the register to AFGR64 and return the real register for the current
589 unsigned getAFGR64Reg() const {
590 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
591 if (RegIdx.Index % 2 != 0)
592 AsmParser.Warning(StartLoc, "Float register should be even.");
593 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
594 .getRegister(RegIdx.Index / 2);
597 /// Coerce the register to FGR64 and return the real register for the current
599 unsigned getFGR64Reg() const {
600 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
601 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
602 .getRegister(RegIdx.Index);
605 /// Coerce the register to FGR32 and return the real register for the current
607 unsigned getFGR32Reg() const {
608 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
609 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
610 .getRegister(RegIdx.Index);
613 /// Coerce the register to FGRH32 and return the real register for the current
615 unsigned getFGRH32Reg() const {
616 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
617 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
618 .getRegister(RegIdx.Index);
621 /// Coerce the register to FCC and return the real register for the current
623 unsigned getFCCReg() const {
624 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
625 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
626 .getRegister(RegIdx.Index);
629 /// Coerce the register to MSA128 and return the real register for the current
631 unsigned getMSA128Reg() const {
632 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
633 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
635 unsigned ClassID = Mips::MSA128BRegClassID;
636 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
639 /// Coerce the register to MSACtrl and return the real register for the
641 unsigned getMSACtrlReg() const {
642 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
643 unsigned ClassID = Mips::MSACtrlRegClassID;
644 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
647 /// Coerce the register to COP2 and return the real register for the
649 unsigned getCOP2Reg() const {
650 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
651 unsigned ClassID = Mips::COP2RegClassID;
652 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
655 /// Coerce the register to COP3 and return the real register for the
657 unsigned getCOP3Reg() const {
658 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
659 unsigned ClassID = Mips::COP3RegClassID;
660 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
663 /// Coerce the register to ACC64DSP and return the real register for the
665 unsigned getACC64DSPReg() const {
666 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
667 unsigned ClassID = Mips::ACC64DSPRegClassID;
668 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
671 /// Coerce the register to HI32DSP and return the real register for the
673 unsigned getHI32DSPReg() const {
674 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
675 unsigned ClassID = Mips::HI32DSPRegClassID;
676 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
679 /// Coerce the register to LO32DSP and return the real register for the
681 unsigned getLO32DSPReg() const {
682 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
683 unsigned ClassID = Mips::LO32DSPRegClassID;
684 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
687 /// Coerce the register to CCR and return the real register for the
689 unsigned getCCRReg() const {
690 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
691 unsigned ClassID = Mips::CCRRegClassID;
692 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
695 /// Coerce the register to HWRegs and return the real register for the
697 unsigned getHWRegsReg() const {
698 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
699 unsigned ClassID = Mips::HWRegsRegClassID;
700 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
704 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
705 // Add as immediate when possible. Null MCExpr = 0.
707 Inst.addOperand(MCOperand::createImm(0));
708 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
709 Inst.addOperand(MCOperand::createImm(CE->getValue()));
711 Inst.addOperand(MCOperand::createExpr(Expr));
714 void addRegOperands(MCInst &Inst, unsigned N) const {
715 llvm_unreachable("Use a custom parser instead");
718 /// Render the operand to an MCInst as a GPR32
719 /// Asserts if the wrong number of operands are requested, or the operand
720 /// is not a k_RegisterIndex compatible with RegKind_GPR
721 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
722 assert(N == 1 && "Invalid number of operands!");
723 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
726 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
727 assert(N == 1 && "Invalid number of operands!");
728 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
731 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
732 assert(N == 1 && "Invalid number of operands!");
733 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
736 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
737 assert(N == 1 && "Invalid number of operands!");
738 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
741 /// Render the operand to an MCInst as a GPR64
742 /// Asserts if the wrong number of operands are requested, or the operand
743 /// is not a k_RegisterIndex compatible with RegKind_GPR
744 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
745 assert(N == 1 && "Invalid number of operands!");
746 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
749 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
754 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
759 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
762 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
763 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
764 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
768 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
769 assert(N == 1 && "Invalid number of operands!");
770 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
773 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
774 assert(N == 1 && "Invalid number of operands!");
775 Inst.addOperand(MCOperand::createReg(getFCCReg()));
778 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
783 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
788 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
789 assert(N == 1 && "Invalid number of operands!");
790 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
793 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
794 assert(N == 1 && "Invalid number of operands!");
795 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
798 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
799 assert(N == 1 && "Invalid number of operands!");
800 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
803 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
804 assert(N == 1 && "Invalid number of operands!");
805 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
808 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
809 assert(N == 1 && "Invalid number of operands!");
810 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
813 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 1 && "Invalid number of operands!");
815 Inst.addOperand(MCOperand::createReg(getCCRReg()));
818 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
819 assert(N == 1 && "Invalid number of operands!");
820 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
823 void addImmOperands(MCInst &Inst, unsigned N) const {
824 assert(N == 1 && "Invalid number of operands!");
825 const MCExpr *Expr = getImm();
829 void addMemOperands(MCInst &Inst, unsigned N) const {
830 assert(N == 2 && "Invalid number of operands!");
832 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
834 const MCExpr *Expr = getMemOff();
838 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
839 assert(N == 2 && "Invalid number of operands!");
841 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
843 const MCExpr *Expr = getMemOff();
847 void addRegListOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 1 && "Invalid number of operands!");
850 for (auto RegNo : getRegList())
851 Inst.addOperand(MCOperand::createReg(RegNo));
854 void addRegPairOperands(MCInst &Inst, unsigned N) const {
855 assert(N == 2 && "Invalid number of operands!");
856 unsigned RegNo = getRegPair();
857 Inst.addOperand(MCOperand::createReg(RegNo++));
858 Inst.addOperand(MCOperand::createReg(RegNo));
861 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
862 assert(N == 2 && "Invalid number of operands!");
863 for (auto RegNo : getRegList())
864 Inst.addOperand(MCOperand::createReg(RegNo));
867 bool isReg() const override {
868 // As a special case until we sort out the definition of div/divu, pretend
869 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
870 if (isGPRAsmReg() && RegIdx.Index == 0)
873 return Kind == k_PhysRegister;
875 bool isRegIdx() const { return Kind == k_RegisterIndex; }
876 bool isImm() const override { return Kind == k_Immediate; }
877 bool isConstantImm() const {
878 return isImm() && dyn_cast<MCConstantExpr>(getImm());
880 bool isToken() const override {
881 // Note: It's not possible to pretend that other operand kinds are tokens.
882 // The matcher emitter checks tokens first.
883 return Kind == k_Token;
885 bool isMem() const override { return Kind == k_Memory; }
886 bool isConstantMemOff() const {
887 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
889 template <unsigned Bits> bool isMemWithSimmOffset() const {
890 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
892 bool isMemWithGRPMM16Base() const {
893 return isMem() && getMemBase()->isMM16AsmReg();
895 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
896 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
897 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
899 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
900 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
901 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
902 && (getMemBase()->getGPR32Reg() == Mips::SP);
904 bool isRegList16() const {
908 int Size = RegList.List->size();
909 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
910 RegList.List->back() != Mips::RA)
913 int PrevReg = *RegList.List->begin();
914 for (int i = 1; i < Size - 1; i++) {
915 int Reg = (*(RegList.List))[i];
916 if ( Reg != PrevReg + 1)
923 bool isInvNum() const { return Kind == k_Immediate; }
924 bool isLSAImm() const {
925 if (!isConstantImm())
927 int64_t Val = getConstantImm();
928 return 1 <= Val && Val <= 4;
930 bool isRegList() const { return Kind == k_RegList; }
931 bool isMovePRegPair() const {
932 if (Kind != k_RegList || RegList.List->size() != 2)
935 unsigned R0 = RegList.List->front();
936 unsigned R1 = RegList.List->back();
938 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
939 (R0 == Mips::A1 && R1 == Mips::A3) ||
940 (R0 == Mips::A2 && R1 == Mips::A3) ||
941 (R0 == Mips::A0 && R1 == Mips::S5) ||
942 (R0 == Mips::A0 && R1 == Mips::S6) ||
943 (R0 == Mips::A0 && R1 == Mips::A1) ||
944 (R0 == Mips::A0 && R1 == Mips::A2) ||
945 (R0 == Mips::A0 && R1 == Mips::A3))
951 StringRef getToken() const {
952 assert(Kind == k_Token && "Invalid access!");
953 return StringRef(Tok.Data, Tok.Length);
955 bool isRegPair() const { return Kind == k_RegPair; }
957 unsigned getReg() const override {
958 // As a special case until we sort out the definition of div/divu, pretend
959 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
960 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
961 RegIdx.Kind & RegKind_GPR)
962 return getGPR32Reg(); // FIXME: GPR64 too
964 assert(Kind == k_PhysRegister && "Invalid access!");
968 const MCExpr *getImm() const {
969 assert((Kind == k_Immediate) && "Invalid access!");
973 int64_t getConstantImm() const {
974 const MCExpr *Val = getImm();
975 return static_cast<const MCConstantExpr *>(Val)->getValue();
978 MipsOperand *getMemBase() const {
979 assert((Kind == k_Memory) && "Invalid access!");
983 const MCExpr *getMemOff() const {
984 assert((Kind == k_Memory) && "Invalid access!");
988 int64_t getConstantMemOff() const {
989 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
992 const SmallVectorImpl<unsigned> &getRegList() const {
993 assert((Kind == k_RegList) && "Invalid access!");
994 return *(RegList.List);
997 unsigned getRegPair() const {
998 assert((Kind == k_RegPair) && "Invalid access!");
1002 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1003 MipsAsmParser &Parser) {
1004 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1005 Op->Tok.Data = Str.data();
1006 Op->Tok.Length = Str.size();
1012 /// Create a numeric register (e.g. $1). The exact register remains
1013 /// unresolved until an instruction successfully matches
1014 static std::unique_ptr<MipsOperand>
1015 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1016 SMLoc E, MipsAsmParser &Parser) {
1017 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1018 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1021 /// Create a register that is definitely a GPR.
1022 /// This is typically only used for named registers such as $gp.
1023 static std::unique_ptr<MipsOperand>
1024 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1025 MipsAsmParser &Parser) {
1026 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1029 /// Create a register that is definitely a FGR.
1030 /// This is typically only used for named registers such as $f0.
1031 static std::unique_ptr<MipsOperand>
1032 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1033 MipsAsmParser &Parser) {
1034 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1037 /// Create a register that is definitely a HWReg.
1038 /// This is typically only used for named registers such as $hwr_cpunum.
1039 static std::unique_ptr<MipsOperand>
1040 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1041 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1042 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1045 /// Create a register that is definitely an FCC.
1046 /// This is typically only used for named registers such as $fcc0.
1047 static std::unique_ptr<MipsOperand>
1048 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1049 MipsAsmParser &Parser) {
1050 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1053 /// Create a register that is definitely an ACC.
1054 /// This is typically only used for named registers such as $ac0.
1055 static std::unique_ptr<MipsOperand>
1056 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1057 MipsAsmParser &Parser) {
1058 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1061 /// Create a register that is definitely an MSA128.
1062 /// This is typically only used for named registers such as $w0.
1063 static std::unique_ptr<MipsOperand>
1064 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1065 SMLoc E, MipsAsmParser &Parser) {
1066 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1069 /// Create a register that is definitely an MSACtrl.
1070 /// This is typically only used for named registers such as $msaaccess.
1071 static std::unique_ptr<MipsOperand>
1072 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1073 SMLoc E, MipsAsmParser &Parser) {
1074 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1077 static std::unique_ptr<MipsOperand>
1078 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1079 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1086 static std::unique_ptr<MipsOperand>
1087 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1088 SMLoc E, MipsAsmParser &Parser) {
1089 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1090 Op->Mem.Base = Base.release();
1097 static std::unique_ptr<MipsOperand>
1098 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1099 MipsAsmParser &Parser) {
1100 assert (Regs.size() > 0 && "Empty list not allowed");
1102 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1103 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1104 Op->StartLoc = StartLoc;
1105 Op->EndLoc = EndLoc;
1109 static std::unique_ptr<MipsOperand>
1110 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1111 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1112 Op->RegIdx.Index = RegNo;
1118 bool isGPRAsmReg() const {
1119 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1121 bool isMM16AsmReg() const {
1122 if (!(isRegIdx() && RegIdx.Kind))
1124 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1125 || RegIdx.Index == 16 || RegIdx.Index == 17);
1127 bool isMM16AsmRegZero() const {
1128 if (!(isRegIdx() && RegIdx.Kind))
1130 return (RegIdx.Index == 0 ||
1131 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1132 RegIdx.Index == 17);
1134 bool isMM16AsmRegMoveP() const {
1135 if (!(isRegIdx() && RegIdx.Kind))
1137 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1138 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1140 bool isFGRAsmReg() const {
1141 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1142 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1144 bool isHWRegsAsmReg() const {
1145 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1147 bool isCCRAsmReg() const {
1148 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1150 bool isFCCAsmReg() const {
1151 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1153 if (!AsmParser.hasEightFccRegisters())
1154 return RegIdx.Index == 0;
1155 return RegIdx.Index <= 7;
1157 bool isACCAsmReg() const {
1158 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1160 bool isCOP2AsmReg() const {
1161 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1163 bool isCOP3AsmReg() const {
1164 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1166 bool isMSA128AsmReg() const {
1167 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1169 bool isMSACtrlAsmReg() const {
1170 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1173 /// getStartLoc - Get the location of the first token of this operand.
1174 SMLoc getStartLoc() const override { return StartLoc; }
1175 /// getEndLoc - Get the location of the last token of this operand.
1176 SMLoc getEndLoc() const override { return EndLoc; }
1178 virtual ~MipsOperand() {
1186 delete RegList.List;
1187 case k_PhysRegister:
1188 case k_RegisterIndex:
1195 void print(raw_ostream &OS) const override {
1204 Mem.Base->print(OS);
1209 case k_PhysRegister:
1210 OS << "PhysReg<" << PhysReg.Num << ">";
1212 case k_RegisterIndex:
1213 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1220 for (auto Reg : (*RegList.List))
1225 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1229 }; // class MipsOperand
1233 extern const MCInstrDesc MipsInsts[];
1235 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1236 return MipsInsts[Opcode];
1239 static bool hasShortDelaySlot(unsigned Opcode) {
1242 case Mips::JALRS_MM:
1243 case Mips::JALRS16_MM:
1244 case Mips::BGEZALS_MM:
1245 case Mips::BLTZALS_MM:
1252 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1253 SmallVectorImpl<MCInst> &Instructions) {
1254 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1258 if (MCID.isBranch() || MCID.isCall()) {
1259 const unsigned Opcode = Inst.getOpcode();
1269 assert(hasCnMips() && "instruction only valid for octeon cpus");
1276 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1277 Offset = Inst.getOperand(2);
1278 if (!Offset.isImm())
1279 break; // We'll deal with this situation later on when applying fixups.
1280 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1281 return Error(IDLoc, "branch target out of range");
1282 if (OffsetToAlignment(Offset.getImm(),
1283 1LL << (inMicroMipsMode() ? 1 : 2)))
1284 return Error(IDLoc, "branch to misaligned address");
1298 case Mips::BGEZAL_MM:
1299 case Mips::BLTZAL_MM:
1302 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1303 Offset = Inst.getOperand(1);
1304 if (!Offset.isImm())
1305 break; // We'll deal with this situation later on when applying fixups.
1306 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1307 return Error(IDLoc, "branch target out of range");
1308 if (OffsetToAlignment(Offset.getImm(),
1309 1LL << (inMicroMipsMode() ? 1 : 2)))
1310 return Error(IDLoc, "branch to misaligned address");
1312 case Mips::BEQZ16_MM:
1313 case Mips::BNEZ16_MM:
1314 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1315 Offset = Inst.getOperand(1);
1316 if (!Offset.isImm())
1317 break; // We'll deal with this situation later on when applying fixups.
1318 if (!isIntN(8, Offset.getImm()))
1319 return Error(IDLoc, "branch target out of range");
1320 if (OffsetToAlignment(Offset.getImm(), 2LL))
1321 return Error(IDLoc, "branch to misaligned address");
1326 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1327 // We still accept it but it is a normal nop.
1328 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1329 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1330 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1335 const unsigned Opcode = Inst.getOpcode();
1347 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1348 // The offset is handled above
1349 Opnd = Inst.getOperand(1);
1351 return Error(IDLoc, "expected immediate operand kind");
1352 Imm = Opnd.getImm();
1353 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1354 Opcode == Mips::BBIT1 ? 63 : 31))
1355 return Error(IDLoc, "immediate operand value out of range");
1357 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1359 Inst.getOperand(1).setImm(Imm - 32);
1367 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1369 Opnd = Inst.getOperand(3);
1371 return Error(IDLoc, "expected immediate operand kind");
1372 Imm = Opnd.getImm();
1373 if (Imm < 0 || Imm > 31)
1374 return Error(IDLoc, "immediate operand value out of range");
1376 Opnd = Inst.getOperand(2);
1378 return Error(IDLoc, "expected immediate operand kind");
1379 Imm = Opnd.getImm();
1380 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1381 Opcode == Mips::EXTS ? 63 : 31))
1382 return Error(IDLoc, "immediate operand value out of range");
1384 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1385 Inst.getOperand(2).setImm(Imm - 32);
1391 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1392 Opnd = Inst.getOperand(2);
1394 return Error(IDLoc, "expected immediate operand kind");
1395 Imm = Opnd.getImm();
1396 if (!isInt<10>(Imm))
1397 return Error(IDLoc, "immediate operand value out of range");
1402 if (MCID.mayLoad() || MCID.mayStore()) {
1403 // Check the offset of memory operand, if it is a symbol
1404 // reference or immediate we may have to expand instructions.
1405 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1406 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1407 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1408 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1409 MCOperand &Op = Inst.getOperand(i);
1411 int MemOffset = Op.getImm();
1412 if (MemOffset < -32768 || MemOffset > 32767) {
1413 // Offset can't exceed 16bit value.
1414 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1417 } else if (Op.isExpr()) {
1418 const MCExpr *Expr = Op.getExpr();
1419 if (Expr->getKind() == MCExpr::SymbolRef) {
1420 const MCSymbolRefExpr *SR =
1421 static_cast<const MCSymbolRefExpr *>(Expr);
1422 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1424 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1427 } else if (!isEvaluated(Expr)) {
1428 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1436 if (inMicroMipsMode()) {
1437 if (MCID.mayLoad()) {
1438 // Try to create 16-bit GP relative load instruction.
1439 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1440 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1441 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1442 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1443 MCOperand &Op = Inst.getOperand(i);
1445 int MemOffset = Op.getImm();
1446 MCOperand &DstReg = Inst.getOperand(0);
1447 MCOperand &BaseReg = Inst.getOperand(1);
1448 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1449 getContext().getRegisterInfo()->getRegClass(
1450 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1451 BaseReg.getReg() == Mips::GP) {
1453 TmpInst.setLoc(IDLoc);
1454 TmpInst.setOpcode(Mips::LWGP_MM);
1455 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1456 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1457 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1458 Instructions.push_back(TmpInst);
1466 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1471 switch (Inst.getOpcode()) {
1474 case Mips::ADDIUS5_MM:
1475 Opnd = Inst.getOperand(2);
1477 return Error(IDLoc, "expected immediate operand kind");
1478 Imm = Opnd.getImm();
1479 if (Imm < -8 || Imm > 7)
1480 return Error(IDLoc, "immediate operand value out of range");
1482 case Mips::ADDIUSP_MM:
1483 Opnd = Inst.getOperand(0);
1485 return Error(IDLoc, "expected immediate operand kind");
1486 Imm = Opnd.getImm();
1487 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1489 return Error(IDLoc, "immediate operand value out of range");
1491 case Mips::SLL16_MM:
1492 case Mips::SRL16_MM:
1493 Opnd = Inst.getOperand(2);
1495 return Error(IDLoc, "expected immediate operand kind");
1496 Imm = Opnd.getImm();
1497 if (Imm < 1 || Imm > 8)
1498 return Error(IDLoc, "immediate operand value out of range");
1501 Opnd = Inst.getOperand(1);
1503 return Error(IDLoc, "expected immediate operand kind");
1504 Imm = Opnd.getImm();
1505 if (Imm < -1 || Imm > 126)
1506 return Error(IDLoc, "immediate operand value out of range");
1508 case Mips::ADDIUR2_MM:
1509 Opnd = Inst.getOperand(2);
1511 return Error(IDLoc, "expected immediate operand kind");
1512 Imm = Opnd.getImm();
1513 if (!(Imm == 1 || Imm == -1 ||
1514 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1515 return Error(IDLoc, "immediate operand value out of range");
1517 case Mips::ADDIUR1SP_MM:
1518 Opnd = Inst.getOperand(1);
1520 return Error(IDLoc, "expected immediate operand kind");
1521 Imm = Opnd.getImm();
1522 if (OffsetToAlignment(Imm, 4LL))
1523 return Error(IDLoc, "misaligned immediate operand value");
1524 if (Imm < 0 || Imm > 255)
1525 return Error(IDLoc, "immediate operand value out of range");
1527 case Mips::ANDI16_MM:
1528 Opnd = Inst.getOperand(2);
1530 return Error(IDLoc, "expected immediate operand kind");
1531 Imm = Opnd.getImm();
1532 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1533 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1534 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1535 return Error(IDLoc, "immediate operand value out of range");
1537 case Mips::LBU16_MM:
1538 Opnd = Inst.getOperand(2);
1540 return Error(IDLoc, "expected immediate operand kind");
1541 Imm = Opnd.getImm();
1542 if (Imm < -1 || Imm > 14)
1543 return Error(IDLoc, "immediate operand value out of range");
1546 Opnd = Inst.getOperand(2);
1548 return Error(IDLoc, "expected immediate operand kind");
1549 Imm = Opnd.getImm();
1550 if (Imm < 0 || Imm > 15)
1551 return Error(IDLoc, "immediate operand value out of range");
1553 case Mips::LHU16_MM:
1555 Opnd = Inst.getOperand(2);
1557 return Error(IDLoc, "expected immediate operand kind");
1558 Imm = Opnd.getImm();
1559 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1560 return Error(IDLoc, "immediate operand value out of range");
1564 Opnd = Inst.getOperand(2);
1566 return Error(IDLoc, "expected immediate operand kind");
1567 Imm = Opnd.getImm();
1568 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1569 return Error(IDLoc, "immediate operand value out of range");
1573 Opnd = Inst.getOperand(2);
1575 return Error(IDLoc, "expected immediate operand kind");
1576 Imm = Opnd.getImm();
1577 if (!isUInt<5>(Imm))
1578 return Error(IDLoc, "immediate operand value out of range");
1580 case Mips::ADDIUPC_MM:
1581 MCOperand Opnd = Inst.getOperand(1);
1583 return Error(IDLoc, "expected immediate operand kind");
1584 int Imm = Opnd.getImm();
1585 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1586 return Error(IDLoc, "immediate operand value out of range");
1591 if (needsExpansion(Inst)) {
1592 if (expandInstruction(Inst, IDLoc, Instructions))
1595 Instructions.push_back(Inst);
1597 // If this instruction has a delay slot and .set reorder is active,
1598 // emit a NOP after it.
1599 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1600 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1605 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1607 switch (Inst.getOpcode()) {
1608 case Mips::LoadImm32:
1609 case Mips::LoadImm64:
1610 case Mips::LoadAddrImm32:
1611 case Mips::LoadAddrReg32:
1612 case Mips::B_MM_Pseudo:
1615 case Mips::JalOneReg:
1616 case Mips::JalTwoReg:
1623 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1624 SmallVectorImpl<MCInst> &Instructions) {
1625 switch (Inst.getOpcode()) {
1626 default: llvm_unreachable("unimplemented expansion");
1627 case Mips::LoadImm32:
1628 return expandLoadImm(Inst, true, IDLoc, Instructions);
1629 case Mips::LoadImm64:
1630 return expandLoadImm(Inst, false, IDLoc, Instructions);
1631 case Mips::LoadAddrImm32:
1632 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1633 case Mips::LoadAddrReg32:
1634 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1635 case Mips::B_MM_Pseudo:
1636 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1639 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1640 case Mips::JalOneReg:
1641 case Mips::JalTwoReg:
1642 return expandJalWithRegs(Inst, IDLoc, Instructions);
1647 template <unsigned ShiftAmount>
1648 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1649 SmallVectorImpl<MCInst> &Instructions) {
1651 if (ShiftAmount >= 32) {
1652 tmpInst.setOpcode(Mips::DSLL32);
1653 tmpInst.addOperand(MCOperand::createReg(RegNo));
1654 tmpInst.addOperand(MCOperand::createReg(RegNo));
1655 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1656 tmpInst.setLoc(IDLoc);
1657 Instructions.push_back(tmpInst);
1659 } else if (ShiftAmount > 0) {
1660 tmpInst.setOpcode(Mips::DSLL);
1661 tmpInst.addOperand(MCOperand::createReg(RegNo));
1662 tmpInst.addOperand(MCOperand::createReg(RegNo));
1663 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1664 tmpInst.setLoc(IDLoc);
1665 Instructions.push_back(tmpInst);
1668 // There's no need for an ORi if the immediate is 0.
1669 if (Operand.isImm() && Operand.getImm() == 0)
1672 tmpInst.setOpcode(Mips::ORi);
1673 tmpInst.addOperand(MCOperand::createReg(RegNo));
1674 tmpInst.addOperand(MCOperand::createReg(RegNo));
1675 tmpInst.addOperand(Operand);
1676 tmpInst.setLoc(IDLoc);
1677 Instructions.push_back(tmpInst);
1680 template <unsigned ShiftAmount>
1681 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1682 SmallVectorImpl<MCInst> &Instructions) {
1683 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1688 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1689 SmallVectorImpl<MCInst> &Instructions) {
1690 // Create a JALR instruction which is going to replace the pseudo-JAL.
1692 JalrInst.setLoc(IDLoc);
1693 const MCOperand FirstRegOp = Inst.getOperand(0);
1694 const unsigned Opcode = Inst.getOpcode();
1696 if (Opcode == Mips::JalOneReg) {
1697 // jal $rs => jalr $rs
1698 if (inMicroMipsMode()) {
1699 JalrInst.setOpcode(Mips::JALR16_MM);
1700 JalrInst.addOperand(FirstRegOp);
1702 JalrInst.setOpcode(Mips::JALR);
1703 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1704 JalrInst.addOperand(FirstRegOp);
1706 } else if (Opcode == Mips::JalTwoReg) {
1707 // jal $rd, $rs => jalr $rd, $rs
1708 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1709 JalrInst.addOperand(FirstRegOp);
1710 const MCOperand SecondRegOp = Inst.getOperand(1);
1711 JalrInst.addOperand(SecondRegOp);
1713 Instructions.push_back(JalrInst);
1715 // If .set reorder is active, emit a NOP after it.
1716 if (AssemblerOptions.back()->isReorder()) {
1717 // This is a 32-bit NOP because these 2 pseudo-instructions
1718 // do not have a short delay slot.
1720 NopInst.setOpcode(Mips::SLL);
1721 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1722 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1723 NopInst.addOperand(MCOperand::createImm(0));
1724 Instructions.push_back(NopInst);
1730 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1731 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1732 SmallVectorImpl<MCInst> &Instructions) {
1733 if (!Is32BitImm && !isGP64bit()) {
1734 Error(IDLoc, "instruction requires a 64-bit architecture");
1738 bool UseSrcReg = false;
1739 if (SrcReg != Mips::NoRegister)
1744 tmpInst.setLoc(IDLoc);
1745 // FIXME: gas has a special case for values that are 000...1111, which
1746 // becomes a li -1 and then a dsrl
1747 if (0 <= ImmValue && ImmValue <= 65535) {
1748 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1749 // li d,j => ori d,$zero,j
1751 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1752 tmpInst.setOpcode(Mips::ORi);
1753 tmpInst.addOperand(MCOperand::createReg(DstReg));
1754 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1755 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1756 Instructions.push_back(tmpInst);
1757 } else if (ImmValue < 0 && ImmValue >= -32768) {
1758 // For negative signed 16-bit values (-32768 <= j < 0):
1759 // li d,j => addiu d,$zero,j
1761 SrcReg = Mips::ZERO;
1762 tmpInst.setOpcode(Mips::ADDiu);
1763 tmpInst.addOperand(MCOperand::createReg(DstReg));
1764 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1765 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1766 Instructions.push_back(tmpInst);
1767 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1768 warnIfNoMacro(IDLoc);
1770 // For all other values which are representable as a 32-bit integer:
1771 // li d,j => lui d,hi16(j)
1773 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1774 uint16_t Bits15To0 = ImmValue & 0xffff;
1776 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1777 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1779 tmpInst.setOpcode(Mips::ORi);
1780 tmpInst.addOperand(MCOperand::createReg(DstReg));
1781 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1782 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1783 tmpInst.setLoc(IDLoc);
1784 Instructions.push_back(tmpInst);
1785 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1786 createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
1788 tmpInst.setOpcode(Mips::LUi);
1789 tmpInst.addOperand(MCOperand::createReg(DstReg));
1790 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1791 Instructions.push_back(tmpInst);
1793 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1796 createAddu(DstReg, DstReg, SrcReg, Instructions);
1798 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1800 Error(IDLoc, "instruction requires a 32-bit immediate");
1803 warnIfNoMacro(IDLoc);
1805 // <------- lo32 ------>
1806 // <------- hi32 ------>
1807 // <- hi16 -> <- lo16 ->
1808 // _________________________________
1810 // | 16-bits | 16-bits | 16-bits |
1811 // |__________|__________|__________|
1813 // For any 64-bit value that is representable as a 48-bit integer:
1814 // li d,j => lui d,hi16(j)
1815 // ori d,d,hi16(lo32(j))
1817 // ori d,d,lo16(lo32(j))
1818 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1819 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1820 uint16_t Bits15To0 = ImmValue & 0xffff;
1822 tmpInst.setOpcode(Mips::LUi);
1823 tmpInst.addOperand(MCOperand::createReg(DstReg));
1824 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1825 Instructions.push_back(tmpInst);
1826 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1827 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1830 createAddu(DstReg, DstReg, SrcReg, Instructions);
1834 Error(IDLoc, "instruction requires a 32-bit immediate");
1837 warnIfNoMacro(IDLoc);
1839 // <------- hi32 ------> <------- lo32 ------>
1840 // <- hi16 -> <- lo16 ->
1841 // ___________________________________________
1843 // | 16-bits | 16-bits | 16-bits | 16-bits |
1844 // |__________|__________|__________|__________|
1846 // For all other values which are representable as a 64-bit integer:
1847 // li d,j => lui d,hi16(j)
1848 // ori d,d,lo16(hi32(j))
1850 // ori d,d,hi16(lo32(j))
1852 // ori d,d,lo16(lo32(j))
1853 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1854 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1855 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1856 uint16_t Bits15To0 = ImmValue & 0xffff;
1858 tmpInst.setOpcode(Mips::LUi);
1859 tmpInst.addOperand(MCOperand::createReg(DstReg));
1860 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1861 Instructions.push_back(tmpInst);
1862 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1864 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1865 // two left shifts of 16 bits.
1866 if (Bits31To16 == 0) {
1867 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1869 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1870 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1874 createAddu(DstReg, DstReg, SrcReg, Instructions);
1879 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1880 SmallVectorImpl<MCInst> &Instructions) {
1881 const MCOperand &ImmOp = Inst.getOperand(1);
1882 assert(ImmOp.isImm() && "expected immediate operand kind");
1883 const MCOperand &DstRegOp = Inst.getOperand(0);
1884 assert(DstRegOp.isReg() && "expected register operand kind");
1886 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1887 Is32BitImm, IDLoc, Instructions))
1894 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1895 SmallVectorImpl<MCInst> &Instructions) {
1896 const MCOperand &DstRegOp = Inst.getOperand(0);
1897 assert(DstRegOp.isReg() && "expected register operand kind");
1899 const MCOperand &ImmOp = Inst.getOperand(2);
1900 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1901 "expected immediate operand kind");
1902 if (!ImmOp.isImm()) {
1903 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1906 const MCOperand &SrcRegOp = Inst.getOperand(1);
1907 assert(SrcRegOp.isReg() && "expected register operand kind");
1909 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1910 Is32BitImm, IDLoc, Instructions))
1917 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1918 SmallVectorImpl<MCInst> &Instructions) {
1919 const MCOperand &DstRegOp = Inst.getOperand(0);
1920 assert(DstRegOp.isReg() && "expected register operand kind");
1922 const MCOperand &ImmOp = Inst.getOperand(1);
1923 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1924 "expected immediate operand kind");
1925 if (!ImmOp.isImm()) {
1926 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1930 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1931 Is32BitImm, IDLoc, Instructions))
1937 void MipsAsmParser::expandLoadAddressSym(
1938 const MCOperand &DstRegOp, const MCOperand &SymOp, bool Is32BitSym,
1939 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1940 warnIfNoMacro(IDLoc);
1942 if (Is32BitSym && isABI_N64())
1943 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1946 unsigned RegNo = DstRegOp.getReg();
1947 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1948 const MCSymbolRefExpr *HiExpr =
1949 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1950 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1951 const MCSymbolRefExpr *LoExpr =
1952 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1953 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1955 // If it's a 64-bit architecture, expand to:
1956 // la d,sym => lui d,highest(sym)
1957 // ori d,d,higher(sym)
1959 // ori d,d,hi16(sym)
1961 // ori d,d,lo16(sym)
1962 const MCSymbolRefExpr *HighestExpr =
1963 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1964 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1965 const MCSymbolRefExpr *HigherExpr =
1966 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1967 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1969 tmpInst.setOpcode(Mips::LUi);
1970 tmpInst.addOperand(MCOperand::createReg(RegNo));
1971 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1972 Instructions.push_back(tmpInst);
1974 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), RegNo, SMLoc(),
1976 createLShiftOri<16>(MCOperand::createExpr(HiExpr), RegNo, SMLoc(),
1978 createLShiftOri<16>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1981 // Otherwise, expand to:
1982 // la d,sym => lui d,hi16(sym)
1983 // ori d,d,lo16(sym)
1984 tmpInst.setOpcode(Mips::LUi);
1985 tmpInst.addOperand(MCOperand::createReg(RegNo));
1986 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
1987 Instructions.push_back(tmpInst);
1989 createLShiftOri<0>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1994 bool MipsAsmParser::expandUncondBranchMMPseudo(
1995 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1996 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1997 "unexpected number of operands");
1999 MCOperand Offset = Inst.getOperand(0);
2000 if (Offset.isExpr()) {
2002 Inst.setOpcode(Mips::BEQ_MM);
2003 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2004 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2005 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2007 assert(Offset.isImm() && "expected immediate operand kind");
2008 if (isIntN(11, Offset.getImm())) {
2009 // If offset fits into 11 bits then this instruction becomes microMIPS
2010 // 16-bit unconditional branch instruction.
2011 Inst.setOpcode(Mips::B16_MM);
2013 if (!isIntN(17, Offset.getImm()))
2014 Error(IDLoc, "branch target out of range");
2015 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2016 Error(IDLoc, "branch to misaligned address");
2018 Inst.setOpcode(Mips::BEQ_MM);
2019 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2020 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2021 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2024 Instructions.push_back(Inst);
2026 // If .set reorder is active, emit a NOP after the branch instruction.
2027 if (AssemblerOptions.back()->isReorder())
2028 createNop(true, IDLoc, Instructions);
2033 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2034 SmallVectorImpl<MCInst> &Instructions,
2035 bool isLoad, bool isImmOpnd) {
2036 const MCSymbolRefExpr *SR;
2038 unsigned ImmOffset, HiOffset, LoOffset;
2039 const MCExpr *ExprOffset;
2041 // 1st operand is either the source or destination register.
2042 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2043 unsigned RegOpNum = Inst.getOperand(0).getReg();
2044 // 2nd operand is the base register.
2045 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2046 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2047 // 3rd operand is either an immediate or expression.
2049 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2050 ImmOffset = Inst.getOperand(2).getImm();
2051 LoOffset = ImmOffset & 0x0000ffff;
2052 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2053 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2054 if (LoOffset & 0x8000)
2057 ExprOffset = Inst.getOperand(2).getExpr();
2058 // All instructions will have the same location.
2059 TempInst.setLoc(IDLoc);
2060 // These are some of the types of expansions we perform here:
2061 // 1) lw $8, sym => lui $8, %hi(sym)
2062 // lw $8, %lo(sym)($8)
2063 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2065 // lw $8, %lo(offset)($9)
2066 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2068 // lw $8, %lo(offset)($at)
2069 // 4) sw $8, sym => lui $at, %hi(sym)
2070 // sw $8, %lo(sym)($at)
2071 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2073 // sw $8, %lo(offset)($at)
2074 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2075 // ldc1 $f0, %lo(sym)($at)
2077 // For load instructions we can use the destination register as a temporary
2078 // if base and dst are different (examples 1 and 2) and if the base register
2079 // is general purpose otherwise we must use $at (example 6) and error if it's
2080 // not available. For stores we must use $at (examples 4 and 5) because we
2081 // must not clobber the source register setting up the offset.
2082 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2083 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2084 unsigned RegClassIDOp0 =
2085 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2086 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2087 (RegClassIDOp0 == Mips::GPR64RegClassID);
2088 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2089 TmpRegNum = RegOpNum;
2091 // At this point we need AT to perform the expansions and we exit if it is
2093 TmpRegNum = getATReg(IDLoc);
2098 TempInst.setOpcode(Mips::LUi);
2099 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2101 TempInst.addOperand(MCOperand::createImm(HiOffset));
2103 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2104 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2105 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2106 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2108 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2110 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2111 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2114 // Add the instruction to the list.
2115 Instructions.push_back(TempInst);
2116 // Prepare TempInst for next instruction.
2118 // Add temp register to base.
2119 if (BaseRegNum != Mips::ZERO) {
2120 TempInst.setOpcode(Mips::ADDu);
2121 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2122 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2123 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2124 Instructions.push_back(TempInst);
2127 // And finally, create original instruction with low part
2128 // of offset and new base.
2129 TempInst.setOpcode(Inst.getOpcode());
2130 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2131 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2133 TempInst.addOperand(MCOperand::createImm(LoOffset));
2135 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2136 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2137 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2139 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2141 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2142 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2145 Instructions.push_back(TempInst);
2150 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2151 SmallVectorImpl<MCInst> &Instructions) {
2152 unsigned OpNum = Inst.getNumOperands();
2153 unsigned Opcode = Inst.getOpcode();
2154 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2156 assert (Inst.getOperand(OpNum - 1).isImm() &&
2157 Inst.getOperand(OpNum - 2).isReg() &&
2158 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2160 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2161 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2162 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2163 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2164 // It can be implemented as SWM16 or LWM16 instruction.
2165 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2167 Inst.setOpcode(NewOpcode);
2168 Instructions.push_back(Inst);
2172 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2173 SmallVectorImpl<MCInst> &Instructions) {
2175 if (hasShortDelaySlot) {
2176 NopInst.setOpcode(Mips::MOVE16_MM);
2177 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2178 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2180 NopInst.setOpcode(Mips::SLL);
2181 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2182 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2183 NopInst.addOperand(MCOperand::createImm(0));
2185 Instructions.push_back(NopInst);
2188 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2190 SmallVectorImpl<MCInst> &Instructions) {
2192 AdduInst.setOpcode(Mips::ADDu);
2193 AdduInst.addOperand(MCOperand::createReg(DstReg));
2194 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2195 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2196 Instructions.push_back(AdduInst);
2199 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2200 // As described by the Mips32r2 spec, the registers Rd and Rs for
2201 // jalr.hb must be different.
2202 unsigned Opcode = Inst.getOpcode();
2204 if (Opcode == Mips::JALR_HB &&
2205 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2206 return Match_RequiresDifferentSrcAndDst;
2208 return Match_Success;
2211 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2212 OperandVector &Operands,
2214 uint64_t &ErrorInfo,
2215 bool MatchingInlineAsm) {
2218 SmallVector<MCInst, 8> Instructions;
2219 unsigned MatchResult =
2220 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2222 switch (MatchResult) {
2223 case Match_Success: {
2224 if (processInstruction(Inst, IDLoc, Instructions))
2226 for (unsigned i = 0; i < Instructions.size(); i++)
2227 Out.EmitInstruction(Instructions[i], STI);
2230 case Match_MissingFeature:
2231 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2233 case Match_InvalidOperand: {
2234 SMLoc ErrorLoc = IDLoc;
2235 if (ErrorInfo != ~0ULL) {
2236 if (ErrorInfo >= Operands.size())
2237 return Error(IDLoc, "too few operands for instruction");
2239 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2240 if (ErrorLoc == SMLoc())
2244 return Error(ErrorLoc, "invalid operand for instruction");
2246 case Match_MnemonicFail:
2247 return Error(IDLoc, "invalid instruction");
2248 case Match_RequiresDifferentSrcAndDst:
2249 return Error(IDLoc, "source and destination must be different");
2252 llvm_unreachable("Implement any new match types added!");
2255 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2256 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2257 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2258 ") without \".set noat\"");
2261 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2262 if (!AssemblerOptions.back()->isMacro())
2263 Warning(Loc, "macro instruction expanded into multiple instructions");
2267 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2268 SMRange Range, bool ShowColors) {
2269 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2270 Range, SMFixIt(Range, FixMsg),
2274 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2277 CC = StringSwitch<unsigned>(Name)
2313 if (!(isABI_N32() || isABI_N64()))
2316 if (12 <= CC && CC <= 15) {
2317 // Name is one of t4-t7
2318 AsmToken RegTok = getLexer().peekTok();
2319 SMRange RegRange = RegTok.getLocRange();
2321 StringRef FixedName = StringSwitch<StringRef>(Name)
2327 assert(FixedName != "" && "Register name is not one of t4-t7.");
2329 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2330 "Did you mean $" + FixedName + "?", RegRange);
2333 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2334 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2335 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2336 if (8 <= CC && CC <= 11)
2340 CC = StringSwitch<unsigned>(Name)
2352 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2355 CC = StringSwitch<unsigned>(Name)
2356 .Case("hwr_cpunum", 0)
2357 .Case("hwr_synci_step", 1)
2359 .Case("hwr_ccres", 3)
2360 .Case("hwr_ulr", 29)
2366 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2368 if (Name[0] == 'f') {
2369 StringRef NumString = Name.substr(1);
2371 if (NumString.getAsInteger(10, IntVal))
2372 return -1; // This is not an integer.
2373 if (IntVal > 31) // Maximum index for fpu register.
2380 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2382 if (Name.startswith("fcc")) {
2383 StringRef NumString = Name.substr(3);
2385 if (NumString.getAsInteger(10, IntVal))
2386 return -1; // This is not an integer.
2387 if (IntVal > 7) // There are only 8 fcc registers.
2394 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2396 if (Name.startswith("ac")) {
2397 StringRef NumString = Name.substr(2);
2399 if (NumString.getAsInteger(10, IntVal))
2400 return -1; // This is not an integer.
2401 if (IntVal > 3) // There are only 3 acc registers.
2408 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2411 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2420 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2423 CC = StringSwitch<unsigned>(Name)
2426 .Case("msaaccess", 2)
2428 .Case("msamodify", 4)
2429 .Case("msarequest", 5)
2431 .Case("msaunmap", 7)
2437 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2438 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2440 reportParseError(Loc,
2441 "pseudo-instruction requires $at, which is not available");
2444 unsigned AT = getReg(
2445 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2449 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2450 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2453 unsigned MipsAsmParser::getGPR(int RegNo) {
2454 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2458 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2460 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2463 return getReg(RegClass, RegNum);
2466 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2467 MCAsmParser &Parser = getParser();
2468 DEBUG(dbgs() << "parseOperand\n");
2470 // Check if the current operand has a custom associated parser, if so, try to
2471 // custom parse the operand, or fallback to the general approach.
2472 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2473 if (ResTy == MatchOperand_Success)
2475 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2476 // there was a match, but an error occurred, in which case, just return that
2477 // the operand parsing failed.
2478 if (ResTy == MatchOperand_ParseFail)
2481 DEBUG(dbgs() << ".. Generic Parser\n");
2483 switch (getLexer().getKind()) {
2485 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2487 case AsmToken::Dollar: {
2488 // Parse the register.
2489 SMLoc S = Parser.getTok().getLoc();
2491 // Almost all registers have been parsed by custom parsers. There is only
2492 // one exception to this. $zero (and it's alias $0) will reach this point
2493 // for div, divu, and similar instructions because it is not an operand
2494 // to the instruction definition but an explicit register. Special case
2495 // this situation for now.
2496 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2499 // Maybe it is a symbol reference.
2500 StringRef Identifier;
2501 if (Parser.parseIdentifier(Identifier))
2504 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2505 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2506 // Otherwise create a symbol reference.
2508 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2510 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2513 // Else drop to expression parsing.
2514 case AsmToken::LParen:
2515 case AsmToken::Minus:
2516 case AsmToken::Plus:
2517 case AsmToken::Integer:
2518 case AsmToken::Tilde:
2519 case AsmToken::String: {
2520 DEBUG(dbgs() << ".. generic integer\n");
2521 OperandMatchResultTy ResTy = parseImm(Operands);
2522 return ResTy != MatchOperand_Success;
2524 case AsmToken::Percent: {
2525 // It is a symbol reference or constant expression.
2526 const MCExpr *IdVal;
2527 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2528 if (parseRelocOperand(IdVal))
2531 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2533 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2535 } // case AsmToken::Percent
2536 } // switch(getLexer().getKind())
2540 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2541 StringRef RelocStr) {
2543 // Check the type of the expression.
2544 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2545 // It's a constant, evaluate reloc value.
2547 switch (getVariantKind(RelocStr)) {
2548 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2549 // Get the 1st 16-bits.
2550 Val = MCE->getValue() & 0xffff;
2552 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2553 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2554 // 16 bits being negative.
2555 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2557 case MCSymbolRefExpr::VK_Mips_HIGHER:
2558 // Get the 3rd 16-bits.
2559 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2561 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2562 // Get the 4th 16-bits.
2563 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2566 report_fatal_error("unsupported reloc value");
2568 return MCConstantExpr::Create(Val, getContext());
2571 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2572 // It's a symbol, create a symbolic expression from the symbol.
2573 StringRef Symbol = MSRE->getSymbol().getName();
2574 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2575 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2579 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2580 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2582 // Try to create target expression.
2583 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2584 return MipsMCExpr::Create(VK, Expr, getContext());
2586 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2587 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2588 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2592 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2593 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2594 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2597 // Just return the original expression.
2601 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2603 switch (Expr->getKind()) {
2604 case MCExpr::Constant:
2606 case MCExpr::SymbolRef:
2607 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2608 case MCExpr::Binary:
2609 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2610 if (!isEvaluated(BE->getLHS()))
2612 return isEvaluated(BE->getRHS());
2615 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2616 case MCExpr::Target:
2622 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2623 MCAsmParser &Parser = getParser();
2624 Parser.Lex(); // Eat the % token.
2625 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2626 if (Tok.isNot(AsmToken::Identifier))
2629 std::string Str = Tok.getIdentifier();
2631 Parser.Lex(); // Eat the identifier.
2632 // Now make an expression from the rest of the operand.
2633 const MCExpr *IdVal;
2636 if (getLexer().getKind() == AsmToken::LParen) {
2638 Parser.Lex(); // Eat the '(' token.
2639 if (getLexer().getKind() == AsmToken::Percent) {
2640 Parser.Lex(); // Eat the % token.
2641 const AsmToken &nextTok = Parser.getTok();
2642 if (nextTok.isNot(AsmToken::Identifier))
2645 Str += nextTok.getIdentifier();
2646 Parser.Lex(); // Eat the identifier.
2647 if (getLexer().getKind() != AsmToken::LParen)
2652 if (getParser().parseParenExpression(IdVal, EndLoc))
2655 while (getLexer().getKind() == AsmToken::RParen)
2656 Parser.Lex(); // Eat the ')' token.
2659 return true; // Parenthesis must follow the relocation operand.
2661 Res = evaluateRelocExpr(IdVal, Str);
2665 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2667 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2668 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2669 if (ResTy == MatchOperand_Success) {
2670 assert(Operands.size() == 1);
2671 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2672 StartLoc = Operand.getStartLoc();
2673 EndLoc = Operand.getEndLoc();
2675 // AFAIK, we only support numeric registers and named GPR's in CFI
2677 // Don't worry about eating tokens before failing. Using an unrecognised
2678 // register is a parse error.
2679 if (Operand.isGPRAsmReg()) {
2680 // Resolve to GPR32 or GPR64 appropriately.
2681 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2684 return (RegNo == (unsigned)-1);
2687 assert(Operands.size() == 0);
2688 return (RegNo == (unsigned)-1);
2691 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2692 MCAsmParser &Parser = getParser();
2696 while (getLexer().getKind() == AsmToken::LParen)
2699 switch (getLexer().getKind()) {
2702 case AsmToken::Identifier:
2703 case AsmToken::LParen:
2704 case AsmToken::Integer:
2705 case AsmToken::Minus:
2706 case AsmToken::Plus:
2708 Result = getParser().parseParenExpression(Res, S);
2710 Result = (getParser().parseExpression(Res));
2711 while (getLexer().getKind() == AsmToken::RParen)
2714 case AsmToken::Percent:
2715 Result = parseRelocOperand(Res);
2720 MipsAsmParser::OperandMatchResultTy
2721 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2722 MCAsmParser &Parser = getParser();
2723 DEBUG(dbgs() << "parseMemOperand\n");
2724 const MCExpr *IdVal = nullptr;
2726 bool isParenExpr = false;
2727 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2728 // First operand is the offset.
2729 S = Parser.getTok().getLoc();
2731 if (getLexer().getKind() == AsmToken::LParen) {
2736 if (getLexer().getKind() != AsmToken::Dollar) {
2737 if (parseMemOffset(IdVal, isParenExpr))
2738 return MatchOperand_ParseFail;
2740 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2741 if (Tok.isNot(AsmToken::LParen)) {
2742 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2743 if (Mnemonic.getToken() == "la") {
2745 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2746 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2747 return MatchOperand_Success;
2749 if (Tok.is(AsmToken::EndOfStatement)) {
2751 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2753 // Zero register assumed, add a memory operand with ZERO as its base.
2754 // "Base" will be managed by k_Memory.
2755 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2758 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2759 return MatchOperand_Success;
2761 Error(Parser.getTok().getLoc(), "'(' expected");
2762 return MatchOperand_ParseFail;
2765 Parser.Lex(); // Eat the '(' token.
2768 Res = parseAnyRegister(Operands);
2769 if (Res != MatchOperand_Success)
2772 if (Parser.getTok().isNot(AsmToken::RParen)) {
2773 Error(Parser.getTok().getLoc(), "')' expected");
2774 return MatchOperand_ParseFail;
2777 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2779 Parser.Lex(); // Eat the ')' token.
2782 IdVal = MCConstantExpr::Create(0, getContext());
2784 // Replace the register operand with the memory operand.
2785 std::unique_ptr<MipsOperand> op(
2786 static_cast<MipsOperand *>(Operands.back().release()));
2787 // Remove the register from the operands.
2788 // "op" will be managed by k_Memory.
2789 Operands.pop_back();
2790 // Add the memory operand.
2791 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2793 if (IdVal->EvaluateAsAbsolute(Imm))
2794 IdVal = MCConstantExpr::Create(Imm, getContext());
2795 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2796 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2800 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2801 return MatchOperand_Success;
2804 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2805 MCAsmParser &Parser = getParser();
2806 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
2808 SMLoc S = Parser.getTok().getLoc();
2810 if (Sym->isVariable())
2811 Expr = Sym->getVariableValue();
2814 if (Expr->getKind() == MCExpr::SymbolRef) {
2815 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2816 StringRef DefSymbol = Ref->getSymbol().getName();
2817 if (DefSymbol.startswith("$")) {
2818 OperandMatchResultTy ResTy =
2819 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2820 if (ResTy == MatchOperand_Success) {
2823 } else if (ResTy == MatchOperand_ParseFail)
2824 llvm_unreachable("Should never ParseFail");
2827 } else if (Expr->getKind() == MCExpr::Constant) {
2829 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2831 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2838 MipsAsmParser::OperandMatchResultTy
2839 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2840 StringRef Identifier,
2842 int Index = matchCPURegisterName(Identifier);
2844 Operands.push_back(MipsOperand::createGPRReg(
2845 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2846 return MatchOperand_Success;
2849 Index = matchHWRegsRegisterName(Identifier);
2851 Operands.push_back(MipsOperand::createHWRegsReg(
2852 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2853 return MatchOperand_Success;
2856 Index = matchFPURegisterName(Identifier);
2858 Operands.push_back(MipsOperand::createFGRReg(
2859 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2860 return MatchOperand_Success;
2863 Index = matchFCCRegisterName(Identifier);
2865 Operands.push_back(MipsOperand::createFCCReg(
2866 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2867 return MatchOperand_Success;
2870 Index = matchACRegisterName(Identifier);
2872 Operands.push_back(MipsOperand::createACCReg(
2873 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2874 return MatchOperand_Success;
2877 Index = matchMSA128RegisterName(Identifier);
2879 Operands.push_back(MipsOperand::createMSA128Reg(
2880 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2881 return MatchOperand_Success;
2884 Index = matchMSA128CtrlRegisterName(Identifier);
2886 Operands.push_back(MipsOperand::createMSACtrlReg(
2887 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2888 return MatchOperand_Success;
2891 return MatchOperand_NoMatch;
2894 MipsAsmParser::OperandMatchResultTy
2895 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2896 MCAsmParser &Parser = getParser();
2897 auto Token = Parser.getLexer().peekTok(false);
2899 if (Token.is(AsmToken::Identifier)) {
2900 DEBUG(dbgs() << ".. identifier\n");
2901 StringRef Identifier = Token.getIdentifier();
2902 OperandMatchResultTy ResTy =
2903 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2905 } else if (Token.is(AsmToken::Integer)) {
2906 DEBUG(dbgs() << ".. integer\n");
2907 Operands.push_back(MipsOperand::createNumericReg(
2908 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2910 return MatchOperand_Success;
2913 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2915 return MatchOperand_NoMatch;
2918 MipsAsmParser::OperandMatchResultTy
2919 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2920 MCAsmParser &Parser = getParser();
2921 DEBUG(dbgs() << "parseAnyRegister\n");
2923 auto Token = Parser.getTok();
2925 SMLoc S = Token.getLoc();
2927 if (Token.isNot(AsmToken::Dollar)) {
2928 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2929 if (Token.is(AsmToken::Identifier)) {
2930 if (searchSymbolAlias(Operands))
2931 return MatchOperand_Success;
2933 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2934 return MatchOperand_NoMatch;
2936 DEBUG(dbgs() << ".. $\n");
2938 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2939 if (ResTy == MatchOperand_Success) {
2941 Parser.Lex(); // identifier
2946 MipsAsmParser::OperandMatchResultTy
2947 MipsAsmParser::parseImm(OperandVector &Operands) {
2948 MCAsmParser &Parser = getParser();
2949 switch (getLexer().getKind()) {
2951 return MatchOperand_NoMatch;
2952 case AsmToken::LParen:
2953 case AsmToken::Minus:
2954 case AsmToken::Plus:
2955 case AsmToken::Integer:
2956 case AsmToken::Tilde:
2957 case AsmToken::String:
2961 const MCExpr *IdVal;
2962 SMLoc S = Parser.getTok().getLoc();
2963 if (getParser().parseExpression(IdVal))
2964 return MatchOperand_ParseFail;
2966 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2967 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2968 return MatchOperand_Success;
2971 MipsAsmParser::OperandMatchResultTy
2972 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2973 MCAsmParser &Parser = getParser();
2974 DEBUG(dbgs() << "parseJumpTarget\n");
2976 SMLoc S = getLexer().getLoc();
2978 // Integers and expressions are acceptable
2979 OperandMatchResultTy ResTy = parseImm(Operands);
2980 if (ResTy != MatchOperand_NoMatch)
2983 // Registers are a valid target and have priority over symbols.
2984 ResTy = parseAnyRegister(Operands);
2985 if (ResTy != MatchOperand_NoMatch)
2988 const MCExpr *Expr = nullptr;
2989 if (Parser.parseExpression(Expr)) {
2990 // We have no way of knowing if a symbol was consumed so we must ParseFail
2991 return MatchOperand_ParseFail;
2994 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2995 return MatchOperand_Success;
2998 MipsAsmParser::OperandMatchResultTy
2999 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3000 MCAsmParser &Parser = getParser();
3001 const MCExpr *IdVal;
3002 // If the first token is '$' we may have register operand.
3003 if (Parser.getTok().is(AsmToken::Dollar))
3004 return MatchOperand_NoMatch;
3005 SMLoc S = Parser.getTok().getLoc();
3006 if (getParser().parseExpression(IdVal))
3007 return MatchOperand_ParseFail;
3008 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3009 assert(MCE && "Unexpected MCExpr type.");
3010 int64_t Val = MCE->getValue();
3011 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3012 Operands.push_back(MipsOperand::CreateImm(
3013 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
3014 return MatchOperand_Success;
3017 MipsAsmParser::OperandMatchResultTy
3018 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3019 MCAsmParser &Parser = getParser();
3020 switch (getLexer().getKind()) {
3022 return MatchOperand_NoMatch;
3023 case AsmToken::LParen:
3024 case AsmToken::Plus:
3025 case AsmToken::Minus:
3026 case AsmToken::Integer:
3031 SMLoc S = Parser.getTok().getLoc();
3033 if (getParser().parseExpression(Expr))
3034 return MatchOperand_ParseFail;
3037 if (!Expr->EvaluateAsAbsolute(Val)) {
3038 Error(S, "expected immediate value");
3039 return MatchOperand_ParseFail;
3042 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3043 // and because the CPU always adds one to the immediate field, the allowed
3044 // range becomes 1..4. We'll only check the range here and will deal
3045 // with the addition/subtraction when actually decoding/encoding
3047 if (Val < 1 || Val > 4) {
3048 Error(S, "immediate not in range (1..4)");
3049 return MatchOperand_ParseFail;
3053 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3054 return MatchOperand_Success;
3057 MipsAsmParser::OperandMatchResultTy
3058 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3059 MCAsmParser &Parser = getParser();
3060 SmallVector<unsigned, 10> Regs;
3062 unsigned PrevReg = Mips::NoRegister;
3063 bool RegRange = false;
3064 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3066 if (Parser.getTok().isNot(AsmToken::Dollar))
3067 return MatchOperand_ParseFail;
3069 SMLoc S = Parser.getTok().getLoc();
3070 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3071 SMLoc E = getLexer().getLoc();
3072 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3073 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3075 // Remove last register operand because registers from register range
3076 // should be inserted first.
3077 if (RegNo == Mips::RA) {
3078 Regs.push_back(RegNo);
3080 unsigned TmpReg = PrevReg + 1;
3081 while (TmpReg <= RegNo) {
3082 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3083 Error(E, "invalid register operand");
3084 return MatchOperand_ParseFail;
3088 Regs.push_back(TmpReg++);
3094 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3095 (RegNo != Mips::RA)) {
3096 Error(E, "$16 or $31 expected");
3097 return MatchOperand_ParseFail;
3098 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3099 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3100 Error(E, "invalid register operand");
3101 return MatchOperand_ParseFail;
3102 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3103 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3104 Error(E, "consecutive register numbers expected");
3105 return MatchOperand_ParseFail;
3108 Regs.push_back(RegNo);
3111 if (Parser.getTok().is(AsmToken::Minus))
3114 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3115 !Parser.getTok().isNot(AsmToken::Comma)) {
3116 Error(E, "',' or '-' expected");
3117 return MatchOperand_ParseFail;
3120 Lex(); // Consume comma or minus
3121 if (Parser.getTok().isNot(AsmToken::Dollar))
3127 SMLoc E = Parser.getTok().getLoc();
3128 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3129 parseMemOperand(Operands);
3130 return MatchOperand_Success;
3133 MipsAsmParser::OperandMatchResultTy
3134 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3135 MCAsmParser &Parser = getParser();
3137 SMLoc S = Parser.getTok().getLoc();
3138 if (parseAnyRegister(Operands) != MatchOperand_Success)
3139 return MatchOperand_ParseFail;
3141 SMLoc E = Parser.getTok().getLoc();
3142 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3143 unsigned Reg = Op.getGPR32Reg();
3144 Operands.pop_back();
3145 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3146 return MatchOperand_Success;
3149 MipsAsmParser::OperandMatchResultTy
3150 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3151 MCAsmParser &Parser = getParser();
3152 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3153 SmallVector<unsigned, 10> Regs;
3155 if (Parser.getTok().isNot(AsmToken::Dollar))
3156 return MatchOperand_ParseFail;
3158 SMLoc S = Parser.getTok().getLoc();
3160 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3161 return MatchOperand_ParseFail;
3163 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3164 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3165 Regs.push_back(RegNo);
3167 SMLoc E = Parser.getTok().getLoc();
3168 if (Parser.getTok().isNot(AsmToken::Comma)) {
3169 Error(E, "',' expected");
3170 return MatchOperand_ParseFail;
3176 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3177 return MatchOperand_ParseFail;
3179 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3180 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3181 Regs.push_back(RegNo);
3183 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3185 return MatchOperand_Success;
3188 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3190 MCSymbolRefExpr::VariantKind VK =
3191 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3192 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3193 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3194 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3195 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3196 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3197 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3198 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3199 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3200 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3201 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3202 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3203 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3204 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3205 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3206 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3207 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3208 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3209 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3210 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3211 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3212 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3213 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3214 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3215 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3216 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3217 .Default(MCSymbolRefExpr::VK_None);
3219 assert(VK != MCSymbolRefExpr::VK_None);
3224 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3226 /// ::= '(', register, ')'
3227 /// handle it before we iterate so we don't get tripped up by the lack of
3229 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3230 MCAsmParser &Parser = getParser();
3231 if (getLexer().is(AsmToken::LParen)) {
3233 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3235 if (parseOperand(Operands, Name)) {
3236 SMLoc Loc = getLexer().getLoc();
3237 Parser.eatToEndOfStatement();
3238 return Error(Loc, "unexpected token in argument list");
3240 if (Parser.getTok().isNot(AsmToken::RParen)) {
3241 SMLoc Loc = getLexer().getLoc();
3242 Parser.eatToEndOfStatement();
3243 return Error(Loc, "unexpected token, expected ')'");
3246 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3252 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3253 /// either one of these.
3254 /// ::= '[', register, ']'
3255 /// ::= '[', integer, ']'
3256 /// handle it before we iterate so we don't get tripped up by the lack of
3258 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3259 OperandVector &Operands) {
3260 MCAsmParser &Parser = getParser();
3261 if (getLexer().is(AsmToken::LBrac)) {
3263 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3265 if (parseOperand(Operands, Name)) {
3266 SMLoc Loc = getLexer().getLoc();
3267 Parser.eatToEndOfStatement();
3268 return Error(Loc, "unexpected token in argument list");
3270 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3271 SMLoc Loc = getLexer().getLoc();
3272 Parser.eatToEndOfStatement();
3273 return Error(Loc, "unexpected token, expected ']'");
3276 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3282 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3283 SMLoc NameLoc, OperandVector &Operands) {
3284 MCAsmParser &Parser = getParser();
3285 DEBUG(dbgs() << "ParseInstruction\n");
3287 // We have reached first instruction, module directive are now forbidden.
3288 getTargetStreamer().forbidModuleDirective();
3290 // Check if we have valid mnemonic
3291 if (!mnemonicIsValid(Name, 0)) {
3292 Parser.eatToEndOfStatement();
3293 return Error(NameLoc, "unknown instruction");
3295 // First operand in MCInst is instruction mnemonic.
3296 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3298 // Read the remaining operands.
3299 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3300 // Read the first operand.
3301 if (parseOperand(Operands, Name)) {
3302 SMLoc Loc = getLexer().getLoc();
3303 Parser.eatToEndOfStatement();
3304 return Error(Loc, "unexpected token in argument list");
3306 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3308 // AFAIK, parenthesis suffixes are never on the first operand
3310 while (getLexer().is(AsmToken::Comma)) {
3311 Parser.Lex(); // Eat the comma.
3312 // Parse and remember the operand.
3313 if (parseOperand(Operands, Name)) {
3314 SMLoc Loc = getLexer().getLoc();
3315 Parser.eatToEndOfStatement();
3316 return Error(Loc, "unexpected token in argument list");
3318 // Parse bracket and parenthesis suffixes before we iterate
3319 if (getLexer().is(AsmToken::LBrac)) {
3320 if (parseBracketSuffix(Name, Operands))
3322 } else if (getLexer().is(AsmToken::LParen) &&
3323 parseParenSuffix(Name, Operands))
3327 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3328 SMLoc Loc = getLexer().getLoc();
3329 Parser.eatToEndOfStatement();
3330 return Error(Loc, "unexpected token in argument list");
3332 Parser.Lex(); // Consume the EndOfStatement.
3336 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3337 MCAsmParser &Parser = getParser();
3338 SMLoc Loc = getLexer().getLoc();
3339 Parser.eatToEndOfStatement();
3340 return Error(Loc, ErrorMsg);
3343 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3344 return Error(Loc, ErrorMsg);
3347 bool MipsAsmParser::parseSetNoAtDirective() {
3348 MCAsmParser &Parser = getParser();
3349 // Line should look like: ".set noat".
3351 // Set the $at register to $0.
3352 AssemblerOptions.back()->setATRegIndex(0);
3354 Parser.Lex(); // Eat "noat".
3356 // If this is not the end of the statement, report an error.
3357 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3358 reportParseError("unexpected token, expected end of statement");
3362 getTargetStreamer().emitDirectiveSetNoAt();
3363 Parser.Lex(); // Consume the EndOfStatement.
3367 bool MipsAsmParser::parseSetAtDirective() {
3368 // Line can be: ".set at", which sets $at to $1
3369 // or ".set at=$reg", which sets $at to $reg.
3370 MCAsmParser &Parser = getParser();
3371 Parser.Lex(); // Eat "at".
3373 if (getLexer().is(AsmToken::EndOfStatement)) {
3374 // No register was specified, so we set $at to $1.
3375 AssemblerOptions.back()->setATRegIndex(1);
3377 getTargetStreamer().emitDirectiveSetAt();
3378 Parser.Lex(); // Consume the EndOfStatement.
3382 if (getLexer().isNot(AsmToken::Equal)) {
3383 reportParseError("unexpected token, expected equals sign");
3386 Parser.Lex(); // Eat "=".
3388 if (getLexer().isNot(AsmToken::Dollar)) {
3389 if (getLexer().is(AsmToken::EndOfStatement)) {
3390 reportParseError("no register specified");
3393 reportParseError("unexpected token, expected dollar sign '$'");
3397 Parser.Lex(); // Eat "$".
3399 // Find out what "reg" is.
3401 const AsmToken &Reg = Parser.getTok();
3402 if (Reg.is(AsmToken::Identifier)) {
3403 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3404 } else if (Reg.is(AsmToken::Integer)) {
3405 AtRegNo = Reg.getIntVal();
3407 reportParseError("unexpected token, expected identifier or integer");
3411 // Check if $reg is a valid register. If it is, set $at to $reg.
3412 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3413 reportParseError("invalid register");
3416 Parser.Lex(); // Eat "reg".
3418 // If this is not the end of the statement, report an error.
3419 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3420 reportParseError("unexpected token, expected end of statement");
3424 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3426 Parser.Lex(); // Consume the EndOfStatement.
3430 bool MipsAsmParser::parseSetReorderDirective() {
3431 MCAsmParser &Parser = getParser();
3433 // If this is not the end of the statement, report an error.
3434 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3435 reportParseError("unexpected token, expected end of statement");
3438 AssemblerOptions.back()->setReorder();
3439 getTargetStreamer().emitDirectiveSetReorder();
3440 Parser.Lex(); // Consume the EndOfStatement.
3444 bool MipsAsmParser::parseSetNoReorderDirective() {
3445 MCAsmParser &Parser = getParser();
3447 // If this is not the end of the statement, report an error.
3448 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3449 reportParseError("unexpected token, expected end of statement");
3452 AssemblerOptions.back()->setNoReorder();
3453 getTargetStreamer().emitDirectiveSetNoReorder();
3454 Parser.Lex(); // Consume the EndOfStatement.
3458 bool MipsAsmParser::parseSetMacroDirective() {
3459 MCAsmParser &Parser = getParser();
3461 // If this is not the end of the statement, report an error.
3462 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3463 reportParseError("unexpected token, expected end of statement");
3466 AssemblerOptions.back()->setMacro();
3467 getTargetStreamer().emitDirectiveSetMacro();
3468 Parser.Lex(); // Consume the EndOfStatement.
3472 bool MipsAsmParser::parseSetNoMacroDirective() {
3473 MCAsmParser &Parser = getParser();
3475 // If this is not the end of the statement, report an error.
3476 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3477 reportParseError("unexpected token, expected end of statement");
3480 if (AssemblerOptions.back()->isReorder()) {
3481 reportParseError("`noreorder' must be set before `nomacro'");
3484 AssemblerOptions.back()->setNoMacro();
3485 getTargetStreamer().emitDirectiveSetNoMacro();
3486 Parser.Lex(); // Consume the EndOfStatement.
3490 bool MipsAsmParser::parseSetMsaDirective() {
3491 MCAsmParser &Parser = getParser();
3494 // If this is not the end of the statement, report an error.
3495 if (getLexer().isNot(AsmToken::EndOfStatement))
3496 return reportParseError("unexpected token, expected end of statement");
3498 setFeatureBits(Mips::FeatureMSA, "msa");
3499 getTargetStreamer().emitDirectiveSetMsa();
3503 bool MipsAsmParser::parseSetNoMsaDirective() {
3504 MCAsmParser &Parser = getParser();
3507 // If this is not the end of the statement, report an error.
3508 if (getLexer().isNot(AsmToken::EndOfStatement))
3509 return reportParseError("unexpected token, expected end of statement");
3511 clearFeatureBits(Mips::FeatureMSA, "msa");
3512 getTargetStreamer().emitDirectiveSetNoMsa();
3516 bool MipsAsmParser::parseSetNoDspDirective() {
3517 MCAsmParser &Parser = getParser();
3518 Parser.Lex(); // Eat "nodsp".
3520 // If this is not the end of the statement, report an error.
3521 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3522 reportParseError("unexpected token, expected end of statement");
3526 clearFeatureBits(Mips::FeatureDSP, "dsp");
3527 getTargetStreamer().emitDirectiveSetNoDsp();
3531 bool MipsAsmParser::parseSetMips16Directive() {
3532 MCAsmParser &Parser = getParser();
3533 Parser.Lex(); // Eat "mips16".
3535 // If this is not the end of the statement, report an error.
3536 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3537 reportParseError("unexpected token, expected end of statement");
3541 setFeatureBits(Mips::FeatureMips16, "mips16");
3542 getTargetStreamer().emitDirectiveSetMips16();
3543 Parser.Lex(); // Consume the EndOfStatement.
3547 bool MipsAsmParser::parseSetNoMips16Directive() {
3548 MCAsmParser &Parser = getParser();
3549 Parser.Lex(); // Eat "nomips16".
3551 // If this is not the end of the statement, report an error.
3552 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3553 reportParseError("unexpected token, expected end of statement");
3557 clearFeatureBits(Mips::FeatureMips16, "mips16");
3558 getTargetStreamer().emitDirectiveSetNoMips16();
3559 Parser.Lex(); // Consume the EndOfStatement.
3563 bool MipsAsmParser::parseSetFpDirective() {
3564 MCAsmParser &Parser = getParser();
3565 MipsABIFlagsSection::FpABIKind FpAbiVal;
3566 // Line can be: .set fp=32
3569 Parser.Lex(); // Eat fp token
3570 AsmToken Tok = Parser.getTok();
3571 if (Tok.isNot(AsmToken::Equal)) {
3572 reportParseError("unexpected token, expected equals sign '='");
3575 Parser.Lex(); // Eat '=' token.
3576 Tok = Parser.getTok();
3578 if (!parseFpABIValue(FpAbiVal, ".set"))
3581 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3582 reportParseError("unexpected token, expected end of statement");
3585 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3586 Parser.Lex(); // Consume the EndOfStatement.
3590 bool MipsAsmParser::parseSetPopDirective() {
3591 MCAsmParser &Parser = getParser();
3592 SMLoc Loc = getLexer().getLoc();
3595 if (getLexer().isNot(AsmToken::EndOfStatement))
3596 return reportParseError("unexpected token, expected end of statement");
3598 // Always keep an element on the options "stack" to prevent the user
3599 // from changing the initial options. This is how we remember them.
3600 if (AssemblerOptions.size() == 2)
3601 return reportParseError(Loc, ".set pop with no .set push");
3603 AssemblerOptions.pop_back();
3604 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3606 getTargetStreamer().emitDirectiveSetPop();
3610 bool MipsAsmParser::parseSetPushDirective() {
3611 MCAsmParser &Parser = getParser();
3613 if (getLexer().isNot(AsmToken::EndOfStatement))
3614 return reportParseError("unexpected token, expected end of statement");
3616 // Create a copy of the current assembler options environment and push it.
3617 AssemblerOptions.push_back(
3618 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3620 getTargetStreamer().emitDirectiveSetPush();
3624 bool MipsAsmParser::parseSetAssignment() {
3626 const MCExpr *Value;
3627 MCAsmParser &Parser = getParser();
3629 if (Parser.parseIdentifier(Name))
3630 reportParseError("expected identifier after .set");
3632 if (getLexer().isNot(AsmToken::Comma))
3633 return reportParseError("unexpected token, expected comma");
3636 if (Parser.parseExpression(Value))
3637 return reportParseError("expected valid expression after comma");
3639 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3640 Sym->setVariableValue(Value);
3645 bool MipsAsmParser::parseSetMips0Directive() {
3646 MCAsmParser &Parser = getParser();
3648 if (getLexer().isNot(AsmToken::EndOfStatement))
3649 return reportParseError("unexpected token, expected end of statement");
3651 // Reset assembler options to their initial values.
3652 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3653 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3655 getTargetStreamer().emitDirectiveSetMips0();
3659 bool MipsAsmParser::parseSetArchDirective() {
3660 MCAsmParser &Parser = getParser();
3662 if (getLexer().isNot(AsmToken::Equal))
3663 return reportParseError("unexpected token, expected equals sign");
3667 if (Parser.parseIdentifier(Arch))
3668 return reportParseError("expected arch identifier");
3670 StringRef ArchFeatureName =
3671 StringSwitch<StringRef>(Arch)
3672 .Case("mips1", "mips1")
3673 .Case("mips2", "mips2")
3674 .Case("mips3", "mips3")
3675 .Case("mips4", "mips4")
3676 .Case("mips5", "mips5")
3677 .Case("mips32", "mips32")
3678 .Case("mips32r2", "mips32r2")
3679 .Case("mips32r3", "mips32r3")
3680 .Case("mips32r5", "mips32r5")
3681 .Case("mips32r6", "mips32r6")
3682 .Case("mips64", "mips64")
3683 .Case("mips64r2", "mips64r2")
3684 .Case("mips64r3", "mips64r3")
3685 .Case("mips64r5", "mips64r5")
3686 .Case("mips64r6", "mips64r6")
3687 .Case("cnmips", "cnmips")
3688 .Case("r4000", "mips3") // This is an implementation of Mips3.
3691 if (ArchFeatureName.empty())
3692 return reportParseError("unsupported architecture");
3694 selectArch(ArchFeatureName);
3695 getTargetStreamer().emitDirectiveSetArch(Arch);
3699 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3700 MCAsmParser &Parser = getParser();
3702 if (getLexer().isNot(AsmToken::EndOfStatement))
3703 return reportParseError("unexpected token, expected end of statement");
3707 llvm_unreachable("Unimplemented feature");
3708 case Mips::FeatureDSP:
3709 setFeatureBits(Mips::FeatureDSP, "dsp");
3710 getTargetStreamer().emitDirectiveSetDsp();
3712 case Mips::FeatureMicroMips:
3713 getTargetStreamer().emitDirectiveSetMicroMips();
3715 case Mips::FeatureMips1:
3716 selectArch("mips1");
3717 getTargetStreamer().emitDirectiveSetMips1();
3719 case Mips::FeatureMips2:
3720 selectArch("mips2");
3721 getTargetStreamer().emitDirectiveSetMips2();
3723 case Mips::FeatureMips3:
3724 selectArch("mips3");
3725 getTargetStreamer().emitDirectiveSetMips3();
3727 case Mips::FeatureMips4:
3728 selectArch("mips4");
3729 getTargetStreamer().emitDirectiveSetMips4();
3731 case Mips::FeatureMips5:
3732 selectArch("mips5");
3733 getTargetStreamer().emitDirectiveSetMips5();
3735 case Mips::FeatureMips32:
3736 selectArch("mips32");
3737 getTargetStreamer().emitDirectiveSetMips32();
3739 case Mips::FeatureMips32r2:
3740 selectArch("mips32r2");
3741 getTargetStreamer().emitDirectiveSetMips32R2();
3743 case Mips::FeatureMips32r3:
3744 selectArch("mips32r3");
3745 getTargetStreamer().emitDirectiveSetMips32R3();
3747 case Mips::FeatureMips32r5:
3748 selectArch("mips32r5");
3749 getTargetStreamer().emitDirectiveSetMips32R5();
3751 case Mips::FeatureMips32r6:
3752 selectArch("mips32r6");
3753 getTargetStreamer().emitDirectiveSetMips32R6();
3755 case Mips::FeatureMips64:
3756 selectArch("mips64");
3757 getTargetStreamer().emitDirectiveSetMips64();
3759 case Mips::FeatureMips64r2:
3760 selectArch("mips64r2");
3761 getTargetStreamer().emitDirectiveSetMips64R2();
3763 case Mips::FeatureMips64r3:
3764 selectArch("mips64r3");
3765 getTargetStreamer().emitDirectiveSetMips64R3();
3767 case Mips::FeatureMips64r5:
3768 selectArch("mips64r5");
3769 getTargetStreamer().emitDirectiveSetMips64R5();
3771 case Mips::FeatureMips64r6:
3772 selectArch("mips64r6");
3773 getTargetStreamer().emitDirectiveSetMips64R6();
3779 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3780 MCAsmParser &Parser = getParser();
3781 if (getLexer().isNot(AsmToken::Comma)) {
3782 SMLoc Loc = getLexer().getLoc();
3783 Parser.eatToEndOfStatement();
3784 return Error(Loc, ErrorStr);
3787 Parser.Lex(); // Eat the comma.
3791 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3792 if (AssemblerOptions.back()->isReorder())
3793 Warning(Loc, ".cpload should be inside a noreorder section");
3795 if (inMips16Mode()) {
3796 reportParseError(".cpload is not supported in Mips16 mode");
3800 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3801 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3802 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3803 reportParseError("expected register containing function address");
3807 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3808 if (!RegOpnd.isGPRAsmReg()) {
3809 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3813 // If this is not the end of the statement, report an error.
3814 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3815 reportParseError("unexpected token, expected end of statement");
3819 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3823 bool MipsAsmParser::parseDirectiveCPSetup() {
3824 MCAsmParser &Parser = getParser();
3827 bool SaveIsReg = true;
3829 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3830 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3831 if (ResTy == MatchOperand_NoMatch) {
3832 reportParseError("expected register containing function address");
3833 Parser.eatToEndOfStatement();
3837 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3838 if (!FuncRegOpnd.isGPRAsmReg()) {
3839 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3840 Parser.eatToEndOfStatement();
3844 FuncReg = FuncRegOpnd.getGPR32Reg();
3847 if (!eatComma("unexpected token, expected comma"))
3850 ResTy = parseAnyRegister(TmpReg);
3851 if (ResTy == MatchOperand_NoMatch) {
3852 const AsmToken &Tok = Parser.getTok();
3853 if (Tok.is(AsmToken::Integer)) {
3854 Save = Tok.getIntVal();
3858 reportParseError("expected save register or stack offset");
3859 Parser.eatToEndOfStatement();
3863 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3864 if (!SaveOpnd.isGPRAsmReg()) {
3865 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3866 Parser.eatToEndOfStatement();
3869 Save = SaveOpnd.getGPR32Reg();
3872 if (!eatComma("unexpected token, expected comma"))
3876 if (Parser.parseExpression(Expr)) {
3877 reportParseError("expected expression");
3881 if (Expr->getKind() != MCExpr::SymbolRef) {
3882 reportParseError("expected symbol");
3885 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3887 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3892 bool MipsAsmParser::parseDirectiveNaN() {
3893 MCAsmParser &Parser = getParser();
3894 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3895 const AsmToken &Tok = Parser.getTok();
3897 if (Tok.getString() == "2008") {
3899 getTargetStreamer().emitDirectiveNaN2008();
3901 } else if (Tok.getString() == "legacy") {
3903 getTargetStreamer().emitDirectiveNaNLegacy();
3907 // If we don't recognize the option passed to the .nan
3908 // directive (e.g. no option or unknown option), emit an error.
3909 reportParseError("invalid option in .nan directive");
3913 bool MipsAsmParser::parseDirectiveSet() {
3914 MCAsmParser &Parser = getParser();
3915 // Get the next token.
3916 const AsmToken &Tok = Parser.getTok();
3918 if (Tok.getString() == "noat") {
3919 return parseSetNoAtDirective();
3920 } else if (Tok.getString() == "at") {
3921 return parseSetAtDirective();
3922 } else if (Tok.getString() == "arch") {
3923 return parseSetArchDirective();
3924 } else if (Tok.getString() == "fp") {
3925 return parseSetFpDirective();
3926 } else if (Tok.getString() == "pop") {
3927 return parseSetPopDirective();
3928 } else if (Tok.getString() == "push") {
3929 return parseSetPushDirective();
3930 } else if (Tok.getString() == "reorder") {
3931 return parseSetReorderDirective();
3932 } else if (Tok.getString() == "noreorder") {
3933 return parseSetNoReorderDirective();
3934 } else if (Tok.getString() == "macro") {
3935 return parseSetMacroDirective();
3936 } else if (Tok.getString() == "nomacro") {
3937 return parseSetNoMacroDirective();
3938 } else if (Tok.getString() == "mips16") {
3939 return parseSetMips16Directive();
3940 } else if (Tok.getString() == "nomips16") {
3941 return parseSetNoMips16Directive();
3942 } else if (Tok.getString() == "nomicromips") {
3943 getTargetStreamer().emitDirectiveSetNoMicroMips();
3944 Parser.eatToEndOfStatement();
3946 } else if (Tok.getString() == "micromips") {
3947 return parseSetFeature(Mips::FeatureMicroMips);
3948 } else if (Tok.getString() == "mips0") {
3949 return parseSetMips0Directive();
3950 } else if (Tok.getString() == "mips1") {
3951 return parseSetFeature(Mips::FeatureMips1);
3952 } else if (Tok.getString() == "mips2") {
3953 return parseSetFeature(Mips::FeatureMips2);
3954 } else if (Tok.getString() == "mips3") {
3955 return parseSetFeature(Mips::FeatureMips3);
3956 } else if (Tok.getString() == "mips4") {
3957 return parseSetFeature(Mips::FeatureMips4);
3958 } else if (Tok.getString() == "mips5") {
3959 return parseSetFeature(Mips::FeatureMips5);
3960 } else if (Tok.getString() == "mips32") {
3961 return parseSetFeature(Mips::FeatureMips32);
3962 } else if (Tok.getString() == "mips32r2") {
3963 return parseSetFeature(Mips::FeatureMips32r2);
3964 } else if (Tok.getString() == "mips32r3") {
3965 return parseSetFeature(Mips::FeatureMips32r3);
3966 } else if (Tok.getString() == "mips32r5") {
3967 return parseSetFeature(Mips::FeatureMips32r5);
3968 } else if (Tok.getString() == "mips32r6") {
3969 return parseSetFeature(Mips::FeatureMips32r6);
3970 } else if (Tok.getString() == "mips64") {
3971 return parseSetFeature(Mips::FeatureMips64);
3972 } else if (Tok.getString() == "mips64r2") {
3973 return parseSetFeature(Mips::FeatureMips64r2);
3974 } else if (Tok.getString() == "mips64r3") {
3975 return parseSetFeature(Mips::FeatureMips64r3);
3976 } else if (Tok.getString() == "mips64r5") {
3977 return parseSetFeature(Mips::FeatureMips64r5);
3978 } else if (Tok.getString() == "mips64r6") {
3979 return parseSetFeature(Mips::FeatureMips64r6);
3980 } else if (Tok.getString() == "dsp") {
3981 return parseSetFeature(Mips::FeatureDSP);
3982 } else if (Tok.getString() == "nodsp") {
3983 return parseSetNoDspDirective();
3984 } else if (Tok.getString() == "msa") {
3985 return parseSetMsaDirective();
3986 } else if (Tok.getString() == "nomsa") {
3987 return parseSetNoMsaDirective();
3989 // It is just an identifier, look for an assignment.
3990 parseSetAssignment();
3997 /// parseDataDirective
3998 /// ::= .word [ expression (, expression)* ]
3999 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4000 MCAsmParser &Parser = getParser();
4001 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4003 const MCExpr *Value;
4004 if (getParser().parseExpression(Value))
4007 getParser().getStreamer().EmitValue(Value, Size);
4009 if (getLexer().is(AsmToken::EndOfStatement))
4012 if (getLexer().isNot(AsmToken::Comma))
4013 return Error(L, "unexpected token, expected comma");
4022 /// parseDirectiveGpWord
4023 /// ::= .gpword local_sym
4024 bool MipsAsmParser::parseDirectiveGpWord() {
4025 MCAsmParser &Parser = getParser();
4026 const MCExpr *Value;
4027 // EmitGPRel32Value requires an expression, so we are using base class
4028 // method to evaluate the expression.
4029 if (getParser().parseExpression(Value))
4031 getParser().getStreamer().EmitGPRel32Value(Value);
4033 if (getLexer().isNot(AsmToken::EndOfStatement))
4034 return Error(getLexer().getLoc(),
4035 "unexpected token, expected end of statement");
4036 Parser.Lex(); // Eat EndOfStatement token.
4040 /// parseDirectiveGpDWord
4041 /// ::= .gpdword local_sym
4042 bool MipsAsmParser::parseDirectiveGpDWord() {
4043 MCAsmParser &Parser = getParser();
4044 const MCExpr *Value;
4045 // EmitGPRel64Value requires an expression, so we are using base class
4046 // method to evaluate the expression.
4047 if (getParser().parseExpression(Value))
4049 getParser().getStreamer().EmitGPRel64Value(Value);
4051 if (getLexer().isNot(AsmToken::EndOfStatement))
4052 return Error(getLexer().getLoc(),
4053 "unexpected token, expected end of statement");
4054 Parser.Lex(); // Eat EndOfStatement token.
4058 bool MipsAsmParser::parseDirectiveOption() {
4059 MCAsmParser &Parser = getParser();
4060 // Get the option token.
4061 AsmToken Tok = Parser.getTok();
4062 // At the moment only identifiers are supported.
4063 if (Tok.isNot(AsmToken::Identifier)) {
4064 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4065 Parser.eatToEndOfStatement();
4069 StringRef Option = Tok.getIdentifier();
4071 if (Option == "pic0") {
4072 getTargetStreamer().emitDirectiveOptionPic0();
4074 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4075 Error(Parser.getTok().getLoc(),
4076 "unexpected token, expected end of statement");
4077 Parser.eatToEndOfStatement();
4082 if (Option == "pic2") {
4083 getTargetStreamer().emitDirectiveOptionPic2();
4085 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4086 Error(Parser.getTok().getLoc(),
4087 "unexpected token, expected end of statement");
4088 Parser.eatToEndOfStatement();
4094 Warning(Parser.getTok().getLoc(),
4095 "unknown option, expected 'pic0' or 'pic2'");
4096 Parser.eatToEndOfStatement();
4100 /// parseInsnDirective
4102 bool MipsAsmParser::parseInsnDirective() {
4103 // If this is not the end of the statement, report an error.
4104 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4105 reportParseError("unexpected token, expected end of statement");
4109 // The actual label marking happens in
4110 // MipsELFStreamer::createPendingLabelRelocs().
4111 getTargetStreamer().emitDirectiveInsn();
4113 getParser().Lex(); // Eat EndOfStatement token.
4117 /// parseDirectiveModule
4118 /// ::= .module oddspreg
4119 /// ::= .module nooddspreg
4120 /// ::= .module fp=value
4121 bool MipsAsmParser::parseDirectiveModule() {
4122 MCAsmParser &Parser = getParser();
4123 MCAsmLexer &Lexer = getLexer();
4124 SMLoc L = Lexer.getLoc();
4126 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4127 // TODO : get a better message.
4128 reportParseError(".module directive must appear before any code");
4133 if (Parser.parseIdentifier(Option)) {
4134 reportParseError("expected .module option identifier");
4138 if (Option == "oddspreg") {
4139 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4140 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4142 // If this is not the end of the statement, report an error.
4143 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4144 reportParseError("unexpected token, expected end of statement");
4148 return false; // parseDirectiveModule has finished successfully.
4149 } else if (Option == "nooddspreg") {
4151 Error(L, "'.module nooddspreg' requires the O32 ABI");
4155 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4156 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4158 // If this is not the end of the statement, report an error.
4159 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4160 reportParseError("unexpected token, expected end of statement");
4164 return false; // parseDirectiveModule has finished successfully.
4165 } else if (Option == "fp") {
4166 return parseDirectiveModuleFP();
4168 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4172 /// parseDirectiveModuleFP
4176 bool MipsAsmParser::parseDirectiveModuleFP() {
4177 MCAsmParser &Parser = getParser();
4178 MCAsmLexer &Lexer = getLexer();
4180 if (Lexer.isNot(AsmToken::Equal)) {
4181 reportParseError("unexpected token, expected equals sign '='");
4184 Parser.Lex(); // Eat '=' token.
4186 MipsABIFlagsSection::FpABIKind FpABI;
4187 if (!parseFpABIValue(FpABI, ".module"))
4190 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4191 reportParseError("unexpected token, expected end of statement");
4195 // Emit appropriate flags.
4196 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4197 Parser.Lex(); // Consume the EndOfStatement.
4201 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4202 StringRef Directive) {
4203 MCAsmParser &Parser = getParser();
4204 MCAsmLexer &Lexer = getLexer();
4206 if (Lexer.is(AsmToken::Identifier)) {
4207 StringRef Value = Parser.getTok().getString();
4210 if (Value != "xx") {
4211 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4216 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4220 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4224 if (Lexer.is(AsmToken::Integer)) {
4225 unsigned Value = Parser.getTok().getIntVal();
4228 if (Value != 32 && Value != 64) {
4229 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4235 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4239 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4241 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4249 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4250 MCAsmParser &Parser = getParser();
4251 StringRef IDVal = DirectiveID.getString();
4253 if (IDVal == ".cpload")
4254 return parseDirectiveCpLoad(DirectiveID.getLoc());
4255 if (IDVal == ".dword") {
4256 parseDataDirective(8, DirectiveID.getLoc());
4259 if (IDVal == ".ent") {
4260 StringRef SymbolName;
4262 if (Parser.parseIdentifier(SymbolName)) {
4263 reportParseError("expected identifier after .ent");
4267 // There's an undocumented extension that allows an integer to
4268 // follow the name of the procedure which AFAICS is ignored by GAS.
4269 // Example: .ent foo,2
4270 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4271 if (getLexer().isNot(AsmToken::Comma)) {
4272 // Even though we accept this undocumented extension for compatibility
4273 // reasons, the additional integer argument does not actually change
4274 // the behaviour of the '.ent' directive, so we would like to discourage
4275 // its use. We do this by not referring to the extended version in
4276 // error messages which are not directly related to its use.
4277 reportParseError("unexpected token, expected end of statement");
4280 Parser.Lex(); // Eat the comma.
4281 const MCExpr *DummyNumber;
4282 int64_t DummyNumberVal;
4283 // If the user was explicitly trying to use the extended version,
4284 // we still give helpful extension-related error messages.
4285 if (Parser.parseExpression(DummyNumber)) {
4286 reportParseError("expected number after comma");
4289 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4290 reportParseError("expected an absolute expression after comma");
4295 // If this is not the end of the statement, report an error.
4296 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4297 reportParseError("unexpected token, expected end of statement");
4301 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4303 getTargetStreamer().emitDirectiveEnt(*Sym);
4308 if (IDVal == ".end") {
4309 StringRef SymbolName;
4311 if (Parser.parseIdentifier(SymbolName)) {
4312 reportParseError("expected identifier after .end");
4316 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4317 reportParseError("unexpected token, expected end of statement");
4321 if (CurrentFn == nullptr) {
4322 reportParseError(".end used without .ent");
4326 if ((SymbolName != CurrentFn->getName())) {
4327 reportParseError(".end symbol does not match .ent symbol");
4331 getTargetStreamer().emitDirectiveEnd(SymbolName);
4332 CurrentFn = nullptr;
4336 if (IDVal == ".frame") {
4337 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4338 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4339 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4340 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4341 reportParseError("expected stack register");
4345 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4346 if (!StackRegOpnd.isGPRAsmReg()) {
4347 reportParseError(StackRegOpnd.getStartLoc(),
4348 "expected general purpose register");
4351 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4353 if (Parser.getTok().is(AsmToken::Comma))
4356 reportParseError("unexpected token, expected comma");
4360 // Parse the frame size.
4361 const MCExpr *FrameSize;
4362 int64_t FrameSizeVal;
4364 if (Parser.parseExpression(FrameSize)) {
4365 reportParseError("expected frame size value");
4369 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4370 reportParseError("frame size not an absolute expression");
4374 if (Parser.getTok().is(AsmToken::Comma))
4377 reportParseError("unexpected token, expected comma");
4381 // Parse the return register.
4383 ResTy = parseAnyRegister(TmpReg);
4384 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4385 reportParseError("expected return register");
4389 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4390 if (!ReturnRegOpnd.isGPRAsmReg()) {
4391 reportParseError(ReturnRegOpnd.getStartLoc(),
4392 "expected general purpose register");
4396 // If this is not the end of the statement, report an error.
4397 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4398 reportParseError("unexpected token, expected end of statement");
4402 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4403 ReturnRegOpnd.getGPR32Reg());
4407 if (IDVal == ".set") {
4408 return parseDirectiveSet();
4411 if (IDVal == ".mask" || IDVal == ".fmask") {
4412 // .mask bitmask, frame_offset
4413 // bitmask: One bit for each register used.
4414 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4415 // first register is expected to be saved.
4417 // .mask 0x80000000, -4
4418 // .fmask 0x80000000, -4
4421 // Parse the bitmask
4422 const MCExpr *BitMask;
4425 if (Parser.parseExpression(BitMask)) {
4426 reportParseError("expected bitmask value");
4430 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4431 reportParseError("bitmask not an absolute expression");
4435 if (Parser.getTok().is(AsmToken::Comma))
4438 reportParseError("unexpected token, expected comma");
4442 // Parse the frame_offset
4443 const MCExpr *FrameOffset;
4444 int64_t FrameOffsetVal;
4446 if (Parser.parseExpression(FrameOffset)) {
4447 reportParseError("expected frame offset value");
4451 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4452 reportParseError("frame offset not an absolute expression");
4456 // If this is not the end of the statement, report an error.
4457 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4458 reportParseError("unexpected token, expected end of statement");
4462 if (IDVal == ".mask")
4463 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4465 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4469 if (IDVal == ".nan")
4470 return parseDirectiveNaN();
4472 if (IDVal == ".gpword") {
4473 parseDirectiveGpWord();
4477 if (IDVal == ".gpdword") {
4478 parseDirectiveGpDWord();
4482 if (IDVal == ".word") {
4483 parseDataDirective(4, DirectiveID.getLoc());
4487 if (IDVal == ".option")
4488 return parseDirectiveOption();
4490 if (IDVal == ".abicalls") {
4491 getTargetStreamer().emitDirectiveAbiCalls();
4492 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4493 Error(Parser.getTok().getLoc(),
4494 "unexpected token, expected end of statement");
4496 Parser.eatToEndOfStatement();
4501 if (IDVal == ".cpsetup")
4502 return parseDirectiveCPSetup();
4504 if (IDVal == ".module")
4505 return parseDirectiveModule();
4507 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4508 return parseInternalDirectiveReallowModule();
4510 if (IDVal == ".insn")
4511 return parseInsnDirective();
4516 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4517 // If this is not the end of the statement, report an error.
4518 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4519 reportParseError("unexpected token, expected end of statement");
4523 getTargetStreamer().reallowModuleDirective();
4525 getParser().Lex(); // Eat EndOfStatement token.
4529 extern "C" void LLVMInitializeMipsAsmParser() {
4530 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4531 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4532 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4533 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4536 #define GET_REGISTER_MATCHER
4537 #define GET_MATCHER_IMPLEMENTATION
4538 #include "MipsGenAsmMatcher.inc"