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 uint64_t AllArchRelatedMask =
82 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
83 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
84 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
85 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
86 Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
87 Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
88 Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
89 Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
100 class MipsAsmParser : public MCTargetAsmParser {
101 MipsTargetStreamer &getTargetStreamer() {
102 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
103 return static_cast<MipsTargetStreamer &>(TS);
106 MCSubtargetInfo &STI;
108 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
109 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
110 // nullptr, which indicates that no function is currently
111 // selected. This usually happens after an '.end func'
114 // Print a warning along with its fix-it message at the given range.
115 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
116 SMRange Range, bool ShowColors = true);
118 #define GET_ASSEMBLER_HEADER
119 #include "MipsGenAsmMatcher.inc"
121 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
123 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
124 OperandVector &Operands, MCStreamer &Out,
126 bool MatchingInlineAsm) override;
128 /// Parse a register as used in CFI directives
129 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
131 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
133 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
135 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
136 SMLoc NameLoc, OperandVector &Operands) override;
138 bool ParseDirective(AsmToken DirectiveID) override;
140 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
142 MipsAsmParser::OperandMatchResultTy
143 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
144 StringRef Identifier, SMLoc S);
146 MipsAsmParser::OperandMatchResultTy
147 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
151 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
153 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy
160 parseRegisterPair (OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseMovePRegPair(OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseRegisterList (OperandVector &Operands);
168 bool searchSymbolAlias(OperandVector &Operands);
170 bool parseOperand(OperandVector &, StringRef Mnemonic);
172 bool needsExpansion(MCInst &Inst);
174 // Expands assembly pseudo instructions.
175 // Returns false on success, true otherwise.
176 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
183 bool Is32BitImm, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
186 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
187 SmallVectorImpl<MCInst> &Instructions);
189 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
194 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
195 SmallVectorImpl<MCInst> &Instructions);
197 void expandLoadAddressSym(const MCOperand &DstRegOp, const MCOperand &SymOp,
198 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
200 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
204 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
205 SmallVectorImpl<MCInst> &Instructions);
207 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
208 SmallVectorImpl<MCInst> &Instructions);
210 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
211 SmallVectorImpl<MCInst> &Instructions);
213 bool reportParseError(Twine ErrorMsg);
214 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
216 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
217 bool parseRelocOperand(const MCExpr *&Res);
219 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
221 bool isEvaluated(const MCExpr *Expr);
222 bool parseSetMips0Directive();
223 bool parseSetArchDirective();
224 bool parseSetFeature(uint64_t Feature);
225 bool parseDirectiveCpLoad(SMLoc Loc);
226 bool parseDirectiveCPSetup();
227 bool parseDirectiveNaN();
228 bool parseDirectiveSet();
229 bool parseDirectiveOption();
230 bool parseInsnDirective();
232 bool parseSetAtDirective();
233 bool parseSetNoAtDirective();
234 bool parseSetMacroDirective();
235 bool parseSetNoMacroDirective();
236 bool parseSetMsaDirective();
237 bool parseSetNoMsaDirective();
238 bool parseSetNoDspDirective();
239 bool parseSetReorderDirective();
240 bool parseSetNoReorderDirective();
241 bool parseSetMips16Directive();
242 bool parseSetNoMips16Directive();
243 bool parseSetFpDirective();
244 bool parseSetPopDirective();
245 bool parseSetPushDirective();
247 bool parseSetAssignment();
249 bool parseDataDirective(unsigned Size, SMLoc L);
250 bool parseDirectiveGpWord();
251 bool parseDirectiveGpDWord();
252 bool parseDirectiveModule();
253 bool parseDirectiveModuleFP();
254 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
255 StringRef Directive);
257 bool parseInternalDirectiveReallowModule();
259 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
261 bool eatComma(StringRef ErrorStr);
263 int matchCPURegisterName(StringRef Symbol);
265 int matchHWRegsRegisterName(StringRef Symbol);
267 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
269 int matchFPURegisterName(StringRef Name);
271 int matchFCCRegisterName(StringRef Name);
273 int matchACRegisterName(StringRef Name);
275 int matchMSA128RegisterName(StringRef Name);
277 int matchMSA128CtrlRegisterName(StringRef Name);
279 unsigned getReg(int RC, int RegNo);
281 unsigned getGPR(int RegNo);
283 /// Returns the internal register number for the current AT. Also checks if
284 /// the current AT is unavailable (set to $0) and gives an error if it is.
285 /// This should be used in pseudo-instruction expansions which need AT.
286 unsigned getATReg(SMLoc Loc);
288 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
289 SmallVectorImpl<MCInst> &Instructions);
291 // Helper function that checks if the value of a vector index is within the
292 // boundaries of accepted values for each RegisterKind
293 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
294 bool validateMSAIndex(int Val, int RegKind);
296 // Selects a new architecture by updating the FeatureBits with the necessary
297 // info including implied dependencies.
298 // Internally, it clears all the feature bits related to *any* architecture
299 // and selects the new one using the ToggleFeature functionality of the
300 // MCSubtargetInfo object that handles implied dependencies. The reason we
301 // clear all the arch related bits manually is because ToggleFeature only
302 // clears the features that imply the feature being cleared and not the
303 // features implied by the feature being cleared. This is easier to see
305 // --------------------------------------------------
306 // | Feature | Implies |
307 // | -------------------------------------------------|
308 // | FeatureMips1 | None |
309 // | FeatureMips2 | FeatureMips1 |
310 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
311 // | FeatureMips4 | FeatureMips3 |
313 // --------------------------------------------------
315 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
316 // FeatureMipsGP64 | FeatureMips1)
317 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
318 void selectArch(StringRef ArchFeature) {
319 uint64_t FeatureBits = STI.getFeatureBits();
320 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
321 STI.setFeatureBits(FeatureBits);
322 setAvailableFeatures(
323 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
324 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
327 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
328 if (!(STI.getFeatureBits() & Feature)) {
329 setAvailableFeatures(
330 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
332 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
335 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
336 if (STI.getFeatureBits() & Feature) {
337 setAvailableFeatures(
338 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
340 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
344 enum MipsMatchResultTy {
345 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
346 #define GET_OPERAND_DIAGNOSTIC_TYPES
347 #include "MipsGenAsmMatcher.inc"
348 #undef GET_OPERAND_DIAGNOSTIC_TYPES
352 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
353 const MCInstrInfo &MII, const MCTargetOptions &Options)
354 : MCTargetAsmParser(), STI(sti),
355 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
356 sti.getCPU(), Options)) {
357 MCAsmParserExtension::Initialize(parser);
359 parser.addAliasForDirective(".asciiz", ".asciz");
361 // Initialize the set of available features.
362 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
364 // Remember the initial assembler options. The user can not modify these.
365 AssemblerOptions.push_back(
366 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
368 // Create an assembler options environment for the user to modify.
369 AssemblerOptions.push_back(
370 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
372 getTargetStreamer().updateABIInfo(*this);
374 if (!isABI_O32() && !useOddSPReg() != 0)
375 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
380 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
381 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
383 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
384 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
385 const MipsABIInfo &getABI() const { return ABI; }
386 bool isABI_N32() const { return ABI.IsN32(); }
387 bool isABI_N64() const { return ABI.IsN64(); }
388 bool isABI_O32() const { return ABI.IsO32(); }
389 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
391 bool useOddSPReg() const {
392 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
395 bool inMicroMipsMode() const {
396 return STI.getFeatureBits() & Mips::FeatureMicroMips;
398 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
399 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
400 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
401 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
402 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
403 bool hasMips32() const {
404 return (STI.getFeatureBits() & Mips::FeatureMips32);
406 bool hasMips64() const {
407 return (STI.getFeatureBits() & Mips::FeatureMips64);
409 bool hasMips32r2() const {
410 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
412 bool hasMips64r2() const {
413 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
415 bool hasMips32r3() const {
416 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
418 bool hasMips64r3() const {
419 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
421 bool hasMips32r5() const {
422 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
424 bool hasMips64r5() const {
425 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
427 bool hasMips32r6() const {
428 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
430 bool hasMips64r6() const {
431 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
433 bool hasCnMips() const {
434 return (STI.getFeatureBits() & Mips::FeatureCnMips);
436 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
437 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
438 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
440 bool inMips16Mode() const {
441 return STI.getFeatureBits() & Mips::FeatureMips16;
444 bool useSoftFloat() const {
445 return (STI.getFeatureBits() & Mips::FeatureSoftFloat);
448 /// Warn if RegIndex is the same as the current AT.
449 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
455 /// MipsOperand - Instances of this class represent a parsed Mips machine
457 class MipsOperand : public MCParsedAsmOperand {
459 /// Broad categories of register classes
460 /// The exact class is finalized by the render method.
462 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
463 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
465 RegKind_FCC = 4, /// FCC
466 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
467 RegKind_MSACtrl = 16, /// MSA control registers
468 RegKind_COP2 = 32, /// COP2
469 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
471 RegKind_CCR = 128, /// CCR
472 RegKind_HWRegs = 256, /// HWRegs
473 RegKind_COP3 = 512, /// COP3
475 /// Potentially any (e.g. $1)
476 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
477 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
478 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
483 k_Immediate, /// An immediate (possibly involving symbol references)
484 k_Memory, /// Base + Offset Memory Address
485 k_PhysRegister, /// A physical register from the Mips namespace
486 k_RegisterIndex, /// A register index in one or more RegKind.
487 k_Token, /// A simple token
488 k_RegList, /// A physical register list
489 k_RegPair /// A pair of physical register
493 MipsOperand(KindTy K, MipsAsmParser &Parser)
494 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
497 /// For diagnostics, and checking the assembler temporary
498 MipsAsmParser &AsmParser;
506 unsigned Num; /// Register Number
510 unsigned Index; /// Index into the register class
511 RegKind Kind; /// Bitfield of the kinds it could possibly be
512 const MCRegisterInfo *RegInfo;
525 SmallVector<unsigned, 10> *List;
530 struct PhysRegOp PhysReg;
531 struct RegIdxOp RegIdx;
534 struct RegListOp RegList;
537 SMLoc StartLoc, EndLoc;
539 /// Internal constructor for register kinds
540 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
541 const MCRegisterInfo *RegInfo,
543 MipsAsmParser &Parser) {
544 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
545 Op->RegIdx.Index = Index;
546 Op->RegIdx.RegInfo = RegInfo;
547 Op->RegIdx.Kind = RegKind;
554 /// Coerce the register to GPR32 and return the real register for the current
556 unsigned getGPR32Reg() const {
557 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
558 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
559 unsigned ClassID = Mips::GPR32RegClassID;
560 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
563 /// Coerce the register to GPR32 and return the real register for the current
565 unsigned getGPRMM16Reg() const {
566 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
567 unsigned ClassID = Mips::GPR32RegClassID;
568 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
571 /// Coerce the register to GPR64 and return the real register for the current
573 unsigned getGPR64Reg() const {
574 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
575 unsigned ClassID = Mips::GPR64RegClassID;
576 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
580 /// Coerce the register to AFGR64 and return the real register for the current
582 unsigned getAFGR64Reg() const {
583 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
584 if (RegIdx.Index % 2 != 0)
585 AsmParser.Warning(StartLoc, "Float register should be even.");
586 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
587 .getRegister(RegIdx.Index / 2);
590 /// Coerce the register to FGR64 and return the real register for the current
592 unsigned getFGR64Reg() const {
593 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
594 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
595 .getRegister(RegIdx.Index);
598 /// Coerce the register to FGR32 and return the real register for the current
600 unsigned getFGR32Reg() const {
601 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
602 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
603 .getRegister(RegIdx.Index);
606 /// Coerce the register to FGRH32 and return the real register for the current
608 unsigned getFGRH32Reg() const {
609 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
610 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
611 .getRegister(RegIdx.Index);
614 /// Coerce the register to FCC and return the real register for the current
616 unsigned getFCCReg() const {
617 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
618 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
619 .getRegister(RegIdx.Index);
622 /// Coerce the register to MSA128 and return the real register for the current
624 unsigned getMSA128Reg() const {
625 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
626 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
628 unsigned ClassID = Mips::MSA128BRegClassID;
629 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
632 /// Coerce the register to MSACtrl and return the real register for the
634 unsigned getMSACtrlReg() const {
635 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
636 unsigned ClassID = Mips::MSACtrlRegClassID;
637 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
640 /// Coerce the register to COP2 and return the real register for the
642 unsigned getCOP2Reg() const {
643 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
644 unsigned ClassID = Mips::COP2RegClassID;
645 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
648 /// Coerce the register to COP3 and return the real register for the
650 unsigned getCOP3Reg() const {
651 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
652 unsigned ClassID = Mips::COP3RegClassID;
653 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
656 /// Coerce the register to ACC64DSP and return the real register for the
658 unsigned getACC64DSPReg() const {
659 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
660 unsigned ClassID = Mips::ACC64DSPRegClassID;
661 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
664 /// Coerce the register to HI32DSP and return the real register for the
666 unsigned getHI32DSPReg() const {
667 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
668 unsigned ClassID = Mips::HI32DSPRegClassID;
669 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
672 /// Coerce the register to LO32DSP and return the real register for the
674 unsigned getLO32DSPReg() const {
675 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
676 unsigned ClassID = Mips::LO32DSPRegClassID;
677 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
680 /// Coerce the register to CCR and return the real register for the
682 unsigned getCCRReg() const {
683 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
684 unsigned ClassID = Mips::CCRRegClassID;
685 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
688 /// Coerce the register to HWRegs and return the real register for the
690 unsigned getHWRegsReg() const {
691 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
692 unsigned ClassID = Mips::HWRegsRegClassID;
693 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
697 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
698 // Add as immediate when possible. Null MCExpr = 0.
700 Inst.addOperand(MCOperand::createImm(0));
701 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
702 Inst.addOperand(MCOperand::createImm(CE->getValue()));
704 Inst.addOperand(MCOperand::createExpr(Expr));
707 void addRegOperands(MCInst &Inst, unsigned N) const {
708 llvm_unreachable("Use a custom parser instead");
711 /// Render the operand to an MCInst as a GPR32
712 /// Asserts if the wrong number of operands are requested, or the operand
713 /// is not a k_RegisterIndex compatible with RegKind_GPR
714 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
715 assert(N == 1 && "Invalid number of operands!");
716 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
719 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
720 assert(N == 1 && "Invalid number of operands!");
721 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
724 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
725 assert(N == 1 && "Invalid number of operands!");
726 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
729 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
730 assert(N == 1 && "Invalid number of operands!");
731 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
734 /// Render the operand to an MCInst as a GPR64
735 /// Asserts if the wrong number of operands are requested, or the operand
736 /// is not a k_RegisterIndex compatible with RegKind_GPR
737 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
738 assert(N == 1 && "Invalid number of operands!");
739 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
742 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
743 assert(N == 1 && "Invalid number of operands!");
744 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
747 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
748 assert(N == 1 && "Invalid number of operands!");
749 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
752 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
753 assert(N == 1 && "Invalid number of operands!");
754 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
755 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
756 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
757 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
761 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
762 assert(N == 1 && "Invalid number of operands!");
763 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
766 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
767 assert(N == 1 && "Invalid number of operands!");
768 Inst.addOperand(MCOperand::createReg(getFCCReg()));
771 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
772 assert(N == 1 && "Invalid number of operands!");
773 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
776 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
777 assert(N == 1 && "Invalid number of operands!");
778 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
781 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
782 assert(N == 1 && "Invalid number of operands!");
783 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
786 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
787 assert(N == 1 && "Invalid number of operands!");
788 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
791 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
792 assert(N == 1 && "Invalid number of operands!");
793 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
796 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
797 assert(N == 1 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
801 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
802 assert(N == 1 && "Invalid number of operands!");
803 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
806 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
807 assert(N == 1 && "Invalid number of operands!");
808 Inst.addOperand(MCOperand::createReg(getCCRReg()));
811 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
812 assert(N == 1 && "Invalid number of operands!");
813 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
816 void addImmOperands(MCInst &Inst, unsigned N) const {
817 assert(N == 1 && "Invalid number of operands!");
818 const MCExpr *Expr = getImm();
822 void addMemOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 2 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
827 const MCExpr *Expr = getMemOff();
831 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
832 assert(N == 2 && "Invalid number of operands!");
834 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
836 const MCExpr *Expr = getMemOff();
840 void addRegListOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 1 && "Invalid number of operands!");
843 for (auto RegNo : getRegList())
844 Inst.addOperand(MCOperand::createReg(RegNo));
847 void addRegPairOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 2 && "Invalid number of operands!");
849 unsigned RegNo = getRegPair();
850 Inst.addOperand(MCOperand::createReg(RegNo++));
851 Inst.addOperand(MCOperand::createReg(RegNo));
854 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
855 assert(N == 2 && "Invalid number of operands!");
856 for (auto RegNo : getRegList())
857 Inst.addOperand(MCOperand::createReg(RegNo));
860 bool isReg() const override {
861 // As a special case until we sort out the definition of div/divu, pretend
862 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
863 if (isGPRAsmReg() && RegIdx.Index == 0)
866 return Kind == k_PhysRegister;
868 bool isRegIdx() const { return Kind == k_RegisterIndex; }
869 bool isImm() const override { return Kind == k_Immediate; }
870 bool isConstantImm() const {
871 return isImm() && dyn_cast<MCConstantExpr>(getImm());
873 bool isToken() const override {
874 // Note: It's not possible to pretend that other operand kinds are tokens.
875 // The matcher emitter checks tokens first.
876 return Kind == k_Token;
878 bool isMem() const override { return Kind == k_Memory; }
879 bool isConstantMemOff() const {
880 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
882 template <unsigned Bits> bool isMemWithSimmOffset() const {
883 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
885 bool isMemWithGRPMM16Base() const {
886 return isMem() && getMemBase()->isMM16AsmReg();
888 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
889 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
890 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
892 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
893 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
894 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
895 && (getMemBase()->getGPR32Reg() == Mips::SP);
897 bool isRegList16() const {
901 int Size = RegList.List->size();
902 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
903 RegList.List->back() != Mips::RA)
906 int PrevReg = *RegList.List->begin();
907 for (int i = 1; i < Size - 1; i++) {
908 int Reg = (*(RegList.List))[i];
909 if ( Reg != PrevReg + 1)
916 bool isInvNum() const { return Kind == k_Immediate; }
917 bool isLSAImm() const {
918 if (!isConstantImm())
920 int64_t Val = getConstantImm();
921 return 1 <= Val && Val <= 4;
923 bool isRegList() const { return Kind == k_RegList; }
924 bool isMovePRegPair() const {
925 if (Kind != k_RegList || RegList.List->size() != 2)
928 unsigned R0 = RegList.List->front();
929 unsigned R1 = RegList.List->back();
931 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
932 (R0 == Mips::A1 && R1 == Mips::A3) ||
933 (R0 == Mips::A2 && R1 == Mips::A3) ||
934 (R0 == Mips::A0 && R1 == Mips::S5) ||
935 (R0 == Mips::A0 && R1 == Mips::S6) ||
936 (R0 == Mips::A0 && R1 == Mips::A1) ||
937 (R0 == Mips::A0 && R1 == Mips::A2) ||
938 (R0 == Mips::A0 && R1 == Mips::A3))
944 StringRef getToken() const {
945 assert(Kind == k_Token && "Invalid access!");
946 return StringRef(Tok.Data, Tok.Length);
948 bool isRegPair() const { return Kind == k_RegPair; }
950 unsigned getReg() const override {
951 // As a special case until we sort out the definition of div/divu, pretend
952 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
953 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
954 RegIdx.Kind & RegKind_GPR)
955 return getGPR32Reg(); // FIXME: GPR64 too
957 assert(Kind == k_PhysRegister && "Invalid access!");
961 const MCExpr *getImm() const {
962 assert((Kind == k_Immediate) && "Invalid access!");
966 int64_t getConstantImm() const {
967 const MCExpr *Val = getImm();
968 return static_cast<const MCConstantExpr *>(Val)->getValue();
971 MipsOperand *getMemBase() const {
972 assert((Kind == k_Memory) && "Invalid access!");
976 const MCExpr *getMemOff() const {
977 assert((Kind == k_Memory) && "Invalid access!");
981 int64_t getConstantMemOff() const {
982 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
985 const SmallVectorImpl<unsigned> &getRegList() const {
986 assert((Kind == k_RegList) && "Invalid access!");
987 return *(RegList.List);
990 unsigned getRegPair() const {
991 assert((Kind == k_RegPair) && "Invalid access!");
995 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
996 MipsAsmParser &Parser) {
997 auto Op = make_unique<MipsOperand>(k_Token, Parser);
998 Op->Tok.Data = Str.data();
999 Op->Tok.Length = Str.size();
1005 /// Create a numeric register (e.g. $1). The exact register remains
1006 /// unresolved until an instruction successfully matches
1007 static std::unique_ptr<MipsOperand>
1008 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1009 SMLoc E, MipsAsmParser &Parser) {
1010 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1011 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1014 /// Create a register that is definitely a GPR.
1015 /// This is typically only used for named registers such as $gp.
1016 static std::unique_ptr<MipsOperand>
1017 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1018 MipsAsmParser &Parser) {
1019 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1022 /// Create a register that is definitely a FGR.
1023 /// This is typically only used for named registers such as $f0.
1024 static std::unique_ptr<MipsOperand>
1025 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1026 MipsAsmParser &Parser) {
1027 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1030 /// Create a register that is definitely a HWReg.
1031 /// This is typically only used for named registers such as $hwr_cpunum.
1032 static std::unique_ptr<MipsOperand>
1033 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1034 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1035 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1038 /// Create a register that is definitely an FCC.
1039 /// This is typically only used for named registers such as $fcc0.
1040 static std::unique_ptr<MipsOperand>
1041 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1042 MipsAsmParser &Parser) {
1043 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1046 /// Create a register that is definitely an ACC.
1047 /// This is typically only used for named registers such as $ac0.
1048 static std::unique_ptr<MipsOperand>
1049 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1050 MipsAsmParser &Parser) {
1051 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1054 /// Create a register that is definitely an MSA128.
1055 /// This is typically only used for named registers such as $w0.
1056 static std::unique_ptr<MipsOperand>
1057 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1058 SMLoc E, MipsAsmParser &Parser) {
1059 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1062 /// Create a register that is definitely an MSACtrl.
1063 /// This is typically only used for named registers such as $msaaccess.
1064 static std::unique_ptr<MipsOperand>
1065 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1066 SMLoc E, MipsAsmParser &Parser) {
1067 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1070 static std::unique_ptr<MipsOperand>
1071 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1072 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1079 static std::unique_ptr<MipsOperand>
1080 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1081 SMLoc E, MipsAsmParser &Parser) {
1082 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1083 Op->Mem.Base = Base.release();
1090 static std::unique_ptr<MipsOperand>
1091 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1092 MipsAsmParser &Parser) {
1093 assert (Regs.size() > 0 && "Empty list not allowed");
1095 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1096 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1097 Op->StartLoc = StartLoc;
1098 Op->EndLoc = EndLoc;
1102 static std::unique_ptr<MipsOperand>
1103 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1104 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1105 Op->RegIdx.Index = RegNo;
1111 bool isGPRAsmReg() const {
1112 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1114 bool isMM16AsmReg() const {
1115 if (!(isRegIdx() && RegIdx.Kind))
1117 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1118 || RegIdx.Index == 16 || RegIdx.Index == 17);
1120 bool isMM16AsmRegZero() const {
1121 if (!(isRegIdx() && RegIdx.Kind))
1123 return (RegIdx.Index == 0 ||
1124 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1125 RegIdx.Index == 17);
1127 bool isMM16AsmRegMoveP() const {
1128 if (!(isRegIdx() && RegIdx.Kind))
1130 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1131 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1133 bool isFGRAsmReg() const {
1134 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1135 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1137 bool isHWRegsAsmReg() const {
1138 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1140 bool isCCRAsmReg() const {
1141 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1143 bool isFCCAsmReg() const {
1144 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1146 if (!AsmParser.hasEightFccRegisters())
1147 return RegIdx.Index == 0;
1148 return RegIdx.Index <= 7;
1150 bool isACCAsmReg() const {
1151 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1153 bool isCOP2AsmReg() const {
1154 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1156 bool isCOP3AsmReg() const {
1157 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1159 bool isMSA128AsmReg() const {
1160 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1162 bool isMSACtrlAsmReg() const {
1163 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1166 /// getStartLoc - Get the location of the first token of this operand.
1167 SMLoc getStartLoc() const override { return StartLoc; }
1168 /// getEndLoc - Get the location of the last token of this operand.
1169 SMLoc getEndLoc() const override { return EndLoc; }
1171 virtual ~MipsOperand() {
1179 delete RegList.List;
1180 case k_PhysRegister:
1181 case k_RegisterIndex:
1188 void print(raw_ostream &OS) const override {
1197 Mem.Base->print(OS);
1202 case k_PhysRegister:
1203 OS << "PhysReg<" << PhysReg.Num << ">";
1205 case k_RegisterIndex:
1206 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1213 for (auto Reg : (*RegList.List))
1218 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1222 }; // class MipsOperand
1226 extern const MCInstrDesc MipsInsts[];
1228 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1229 return MipsInsts[Opcode];
1232 static bool hasShortDelaySlot(unsigned Opcode) {
1235 case Mips::JALRS_MM:
1236 case Mips::JALRS16_MM:
1237 case Mips::BGEZALS_MM:
1238 case Mips::BLTZALS_MM:
1245 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1246 SmallVectorImpl<MCInst> &Instructions) {
1247 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1251 if (MCID.isBranch() || MCID.isCall()) {
1252 const unsigned Opcode = Inst.getOpcode();
1262 assert(hasCnMips() && "instruction only valid for octeon cpus");
1269 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1270 Offset = Inst.getOperand(2);
1271 if (!Offset.isImm())
1272 break; // We'll deal with this situation later on when applying fixups.
1273 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1274 return Error(IDLoc, "branch target out of range");
1275 if (OffsetToAlignment(Offset.getImm(),
1276 1LL << (inMicroMipsMode() ? 1 : 2)))
1277 return Error(IDLoc, "branch to misaligned address");
1291 case Mips::BGEZAL_MM:
1292 case Mips::BLTZAL_MM:
1295 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1296 Offset = Inst.getOperand(1);
1297 if (!Offset.isImm())
1298 break; // We'll deal with this situation later on when applying fixups.
1299 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1300 return Error(IDLoc, "branch target out of range");
1301 if (OffsetToAlignment(Offset.getImm(),
1302 1LL << (inMicroMipsMode() ? 1 : 2)))
1303 return Error(IDLoc, "branch to misaligned address");
1305 case Mips::BEQZ16_MM:
1306 case Mips::BNEZ16_MM:
1307 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1308 Offset = Inst.getOperand(1);
1309 if (!Offset.isImm())
1310 break; // We'll deal with this situation later on when applying fixups.
1311 if (!isIntN(8, Offset.getImm()))
1312 return Error(IDLoc, "branch target out of range");
1313 if (OffsetToAlignment(Offset.getImm(), 2LL))
1314 return Error(IDLoc, "branch to misaligned address");
1319 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1320 // We still accept it but it is a normal nop.
1321 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1322 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1323 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1328 const unsigned Opcode = Inst.getOpcode();
1340 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1341 // The offset is handled above
1342 Opnd = Inst.getOperand(1);
1344 return Error(IDLoc, "expected immediate operand kind");
1345 Imm = Opnd.getImm();
1346 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1347 Opcode == Mips::BBIT1 ? 63 : 31))
1348 return Error(IDLoc, "immediate operand value out of range");
1350 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1352 Inst.getOperand(1).setImm(Imm - 32);
1360 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1362 Opnd = Inst.getOperand(3);
1364 return Error(IDLoc, "expected immediate operand kind");
1365 Imm = Opnd.getImm();
1366 if (Imm < 0 || Imm > 31)
1367 return Error(IDLoc, "immediate operand value out of range");
1369 Opnd = Inst.getOperand(2);
1371 return Error(IDLoc, "expected immediate operand kind");
1372 Imm = Opnd.getImm();
1373 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1374 Opcode == Mips::EXTS ? 63 : 31))
1375 return Error(IDLoc, "immediate operand value out of range");
1377 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1378 Inst.getOperand(2).setImm(Imm - 32);
1384 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1385 Opnd = Inst.getOperand(2);
1387 return Error(IDLoc, "expected immediate operand kind");
1388 Imm = Opnd.getImm();
1389 if (!isInt<10>(Imm))
1390 return Error(IDLoc, "immediate operand value out of range");
1395 if (MCID.mayLoad() || MCID.mayStore()) {
1396 // Check the offset of memory operand, if it is a symbol
1397 // reference or immediate we may have to expand instructions.
1398 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1399 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1400 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1401 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1402 MCOperand &Op = Inst.getOperand(i);
1404 int MemOffset = Op.getImm();
1405 if (MemOffset < -32768 || MemOffset > 32767) {
1406 // Offset can't exceed 16bit value.
1407 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1410 } else if (Op.isExpr()) {
1411 const MCExpr *Expr = Op.getExpr();
1412 if (Expr->getKind() == MCExpr::SymbolRef) {
1413 const MCSymbolRefExpr *SR =
1414 static_cast<const MCSymbolRefExpr *>(Expr);
1415 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1417 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1420 } else if (!isEvaluated(Expr)) {
1421 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1429 if (inMicroMipsMode()) {
1430 if (MCID.mayLoad()) {
1431 // Try to create 16-bit GP relative load instruction.
1432 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1433 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1434 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1435 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1436 MCOperand &Op = Inst.getOperand(i);
1438 int MemOffset = Op.getImm();
1439 MCOperand &DstReg = Inst.getOperand(0);
1440 MCOperand &BaseReg = Inst.getOperand(1);
1441 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1442 getContext().getRegisterInfo()->getRegClass(
1443 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1444 BaseReg.getReg() == Mips::GP) {
1446 TmpInst.setLoc(IDLoc);
1447 TmpInst.setOpcode(Mips::LWGP_MM);
1448 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1449 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1450 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1451 Instructions.push_back(TmpInst);
1459 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1464 switch (Inst.getOpcode()) {
1467 case Mips::ADDIUS5_MM:
1468 Opnd = Inst.getOperand(2);
1470 return Error(IDLoc, "expected immediate operand kind");
1471 Imm = Opnd.getImm();
1472 if (Imm < -8 || Imm > 7)
1473 return Error(IDLoc, "immediate operand value out of range");
1475 case Mips::ADDIUSP_MM:
1476 Opnd = Inst.getOperand(0);
1478 return Error(IDLoc, "expected immediate operand kind");
1479 Imm = Opnd.getImm();
1480 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1482 return Error(IDLoc, "immediate operand value out of range");
1484 case Mips::SLL16_MM:
1485 case Mips::SRL16_MM:
1486 Opnd = Inst.getOperand(2);
1488 return Error(IDLoc, "expected immediate operand kind");
1489 Imm = Opnd.getImm();
1490 if (Imm < 1 || Imm > 8)
1491 return Error(IDLoc, "immediate operand value out of range");
1494 Opnd = Inst.getOperand(1);
1496 return Error(IDLoc, "expected immediate operand kind");
1497 Imm = Opnd.getImm();
1498 if (Imm < -1 || Imm > 126)
1499 return Error(IDLoc, "immediate operand value out of range");
1501 case Mips::ADDIUR2_MM:
1502 Opnd = Inst.getOperand(2);
1504 return Error(IDLoc, "expected immediate operand kind");
1505 Imm = Opnd.getImm();
1506 if (!(Imm == 1 || Imm == -1 ||
1507 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1508 return Error(IDLoc, "immediate operand value out of range");
1510 case Mips::ADDIUR1SP_MM:
1511 Opnd = Inst.getOperand(1);
1513 return Error(IDLoc, "expected immediate operand kind");
1514 Imm = Opnd.getImm();
1515 if (OffsetToAlignment(Imm, 4LL))
1516 return Error(IDLoc, "misaligned immediate operand value");
1517 if (Imm < 0 || Imm > 255)
1518 return Error(IDLoc, "immediate operand value out of range");
1520 case Mips::ANDI16_MM:
1521 Opnd = Inst.getOperand(2);
1523 return Error(IDLoc, "expected immediate operand kind");
1524 Imm = Opnd.getImm();
1525 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1526 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1527 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1528 return Error(IDLoc, "immediate operand value out of range");
1530 case Mips::LBU16_MM:
1531 Opnd = Inst.getOperand(2);
1533 return Error(IDLoc, "expected immediate operand kind");
1534 Imm = Opnd.getImm();
1535 if (Imm < -1 || Imm > 14)
1536 return Error(IDLoc, "immediate operand value out of range");
1539 Opnd = Inst.getOperand(2);
1541 return Error(IDLoc, "expected immediate operand kind");
1542 Imm = Opnd.getImm();
1543 if (Imm < 0 || Imm > 15)
1544 return Error(IDLoc, "immediate operand value out of range");
1546 case Mips::LHU16_MM:
1548 Opnd = Inst.getOperand(2);
1550 return Error(IDLoc, "expected immediate operand kind");
1551 Imm = Opnd.getImm();
1552 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1553 return Error(IDLoc, "immediate operand value out of range");
1557 Opnd = Inst.getOperand(2);
1559 return Error(IDLoc, "expected immediate operand kind");
1560 Imm = Opnd.getImm();
1561 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1562 return Error(IDLoc, "immediate operand value out of range");
1566 Opnd = Inst.getOperand(2);
1568 return Error(IDLoc, "expected immediate operand kind");
1569 Imm = Opnd.getImm();
1570 if (!isUInt<5>(Imm))
1571 return Error(IDLoc, "immediate operand value out of range");
1573 case Mips::ADDIUPC_MM:
1574 MCOperand Opnd = Inst.getOperand(1);
1576 return Error(IDLoc, "expected immediate operand kind");
1577 int Imm = Opnd.getImm();
1578 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1579 return Error(IDLoc, "immediate operand value out of range");
1584 if (needsExpansion(Inst)) {
1585 if (expandInstruction(Inst, IDLoc, Instructions))
1588 Instructions.push_back(Inst);
1590 // If this instruction has a delay slot and .set reorder is active,
1591 // emit a NOP after it.
1592 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1593 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1598 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1600 switch (Inst.getOpcode()) {
1601 case Mips::LoadImm32:
1602 case Mips::LoadImm64:
1603 case Mips::LoadAddrImm32:
1604 case Mips::LoadAddrReg32:
1605 case Mips::B_MM_Pseudo:
1608 case Mips::JalOneReg:
1609 case Mips::JalTwoReg:
1616 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1617 SmallVectorImpl<MCInst> &Instructions) {
1618 switch (Inst.getOpcode()) {
1619 default: llvm_unreachable("unimplemented expansion");
1620 case Mips::LoadImm32:
1621 return expandLoadImm(Inst, true, IDLoc, Instructions);
1622 case Mips::LoadImm64:
1623 return expandLoadImm(Inst, false, IDLoc, Instructions);
1624 case Mips::LoadAddrImm32:
1625 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1626 case Mips::LoadAddrReg32:
1627 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1628 case Mips::B_MM_Pseudo:
1629 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1632 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1633 case Mips::JalOneReg:
1634 case Mips::JalTwoReg:
1635 return expandJalWithRegs(Inst, IDLoc, Instructions);
1640 template <unsigned ShiftAmount>
1641 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1642 SmallVectorImpl<MCInst> &Instructions) {
1644 if (ShiftAmount >= 32) {
1645 tmpInst.setOpcode(Mips::DSLL32);
1646 tmpInst.addOperand(MCOperand::createReg(RegNo));
1647 tmpInst.addOperand(MCOperand::createReg(RegNo));
1648 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1649 tmpInst.setLoc(IDLoc);
1650 Instructions.push_back(tmpInst);
1652 } else if (ShiftAmount > 0) {
1653 tmpInst.setOpcode(Mips::DSLL);
1654 tmpInst.addOperand(MCOperand::createReg(RegNo));
1655 tmpInst.addOperand(MCOperand::createReg(RegNo));
1656 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1657 tmpInst.setLoc(IDLoc);
1658 Instructions.push_back(tmpInst);
1661 // There's no need for an ORi if the immediate is 0.
1662 if (Operand.isImm() && Operand.getImm() == 0)
1665 tmpInst.setOpcode(Mips::ORi);
1666 tmpInst.addOperand(MCOperand::createReg(RegNo));
1667 tmpInst.addOperand(MCOperand::createReg(RegNo));
1668 tmpInst.addOperand(Operand);
1669 tmpInst.setLoc(IDLoc);
1670 Instructions.push_back(tmpInst);
1673 template <unsigned ShiftAmount>
1674 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1675 SmallVectorImpl<MCInst> &Instructions) {
1676 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1681 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1682 SmallVectorImpl<MCInst> &Instructions) {
1683 // Create a JALR instruction which is going to replace the pseudo-JAL.
1685 JalrInst.setLoc(IDLoc);
1686 const MCOperand FirstRegOp = Inst.getOperand(0);
1687 const unsigned Opcode = Inst.getOpcode();
1689 if (Opcode == Mips::JalOneReg) {
1690 // jal $rs => jalr $rs
1691 if (inMicroMipsMode()) {
1692 JalrInst.setOpcode(Mips::JALR16_MM);
1693 JalrInst.addOperand(FirstRegOp);
1695 JalrInst.setOpcode(Mips::JALR);
1696 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1697 JalrInst.addOperand(FirstRegOp);
1699 } else if (Opcode == Mips::JalTwoReg) {
1700 // jal $rd, $rs => jalr $rd, $rs
1701 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1702 JalrInst.addOperand(FirstRegOp);
1703 const MCOperand SecondRegOp = Inst.getOperand(1);
1704 JalrInst.addOperand(SecondRegOp);
1706 Instructions.push_back(JalrInst);
1708 // If .set reorder is active, emit a NOP after it.
1709 if (AssemblerOptions.back()->isReorder()) {
1710 // This is a 32-bit NOP because these 2 pseudo-instructions
1711 // do not have a short delay slot.
1713 NopInst.setOpcode(Mips::SLL);
1714 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1715 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1716 NopInst.addOperand(MCOperand::createImm(0));
1717 Instructions.push_back(NopInst);
1723 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1724 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1725 SmallVectorImpl<MCInst> &Instructions) {
1726 if (!Is32BitImm && !isGP64bit()) {
1727 Error(IDLoc, "instruction requires a 64-bit architecture");
1731 bool UseSrcReg = false;
1732 if (SrcReg != Mips::NoRegister)
1737 tmpInst.setLoc(IDLoc);
1738 // FIXME: gas has a special case for values that are 000...1111, which
1739 // becomes a li -1 and then a dsrl
1740 if (0 <= ImmValue && ImmValue <= 65535) {
1741 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1742 // li d,j => ori d,$zero,j
1744 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1745 tmpInst.setOpcode(Mips::ORi);
1746 tmpInst.addOperand(MCOperand::createReg(DstReg));
1747 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1748 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1749 Instructions.push_back(tmpInst);
1750 } else if (ImmValue < 0 && ImmValue >= -32768) {
1751 // For negative signed 16-bit values (-32768 <= j < 0):
1752 // li d,j => addiu d,$zero,j
1754 SrcReg = Mips::ZERO;
1755 tmpInst.setOpcode(Mips::ADDiu);
1756 tmpInst.addOperand(MCOperand::createReg(DstReg));
1757 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1758 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1759 Instructions.push_back(tmpInst);
1760 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1761 // For all other values which are representable as a 32-bit integer:
1762 // li d,j => lui d,hi16(j)
1764 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1765 uint16_t Bits15To0 = ImmValue & 0xffff;
1767 tmpInst.setOpcode(Mips::LUi);
1768 tmpInst.addOperand(MCOperand::createReg(DstReg));
1769 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1770 Instructions.push_back(tmpInst);
1771 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1774 createAddu(DstReg, DstReg, SrcReg, Instructions);
1776 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1778 Error(IDLoc, "instruction requires a 32-bit immediate");
1782 // <------- lo32 ------>
1783 // <------- hi32 ------>
1784 // <- hi16 -> <- lo16 ->
1785 // _________________________________
1787 // | 16-bits | 16-bits | 16-bits |
1788 // |__________|__________|__________|
1790 // For any 64-bit value that is representable as a 48-bit integer:
1791 // li d,j => lui d,hi16(j)
1792 // ori d,d,hi16(lo32(j))
1794 // ori d,d,lo16(lo32(j))
1795 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1796 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1797 uint16_t Bits15To0 = ImmValue & 0xffff;
1799 tmpInst.setOpcode(Mips::LUi);
1800 tmpInst.addOperand(MCOperand::createReg(DstReg));
1801 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1802 Instructions.push_back(tmpInst);
1803 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1804 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1807 createAddu(DstReg, DstReg, SrcReg, Instructions);
1811 Error(IDLoc, "instruction requires a 32-bit immediate");
1815 // <------- hi32 ------> <------- lo32 ------>
1816 // <- hi16 -> <- lo16 ->
1817 // ___________________________________________
1819 // | 16-bits | 16-bits | 16-bits | 16-bits |
1820 // |__________|__________|__________|__________|
1822 // For all other values which are representable as a 64-bit integer:
1823 // li d,j => lui d,hi16(j)
1824 // ori d,d,lo16(hi32(j))
1826 // ori d,d,hi16(lo32(j))
1828 // ori d,d,lo16(lo32(j))
1829 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1830 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1831 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1832 uint16_t Bits15To0 = ImmValue & 0xffff;
1834 tmpInst.setOpcode(Mips::LUi);
1835 tmpInst.addOperand(MCOperand::createReg(DstReg));
1836 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1837 Instructions.push_back(tmpInst);
1838 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1840 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1841 // two left shifts of 16 bits.
1842 if (Bits31To16 == 0) {
1843 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1845 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1846 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1850 createAddu(DstReg, DstReg, SrcReg, Instructions);
1855 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1856 SmallVectorImpl<MCInst> &Instructions) {
1857 const MCOperand &ImmOp = Inst.getOperand(1);
1858 assert(ImmOp.isImm() && "expected immediate operand kind");
1859 const MCOperand &DstRegOp = Inst.getOperand(0);
1860 assert(DstRegOp.isReg() && "expected register operand kind");
1862 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1863 Is32BitImm, IDLoc, Instructions))
1870 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1871 SmallVectorImpl<MCInst> &Instructions) {
1872 const MCOperand &DstRegOp = Inst.getOperand(0);
1873 assert(DstRegOp.isReg() && "expected register operand kind");
1875 const MCOperand &ImmOp = Inst.getOperand(2);
1876 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1877 "expected immediate operand kind");
1878 if (!ImmOp.isImm()) {
1879 expandLoadAddressSym(DstRegOp, ImmOp, IDLoc, Instructions);
1882 const MCOperand &SrcRegOp = Inst.getOperand(1);
1883 assert(SrcRegOp.isReg() && "expected register operand kind");
1885 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1886 Is32BitImm, IDLoc, Instructions))
1893 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1894 SmallVectorImpl<MCInst> &Instructions) {
1895 const MCOperand &DstRegOp = Inst.getOperand(0);
1896 assert(DstRegOp.isReg() && "expected register operand kind");
1898 const MCOperand &ImmOp = Inst.getOperand(1);
1899 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1900 "expected immediate operand kind");
1901 if (!ImmOp.isImm()) {
1902 expandLoadAddressSym(DstRegOp, ImmOp, IDLoc, Instructions);
1906 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1907 Is32BitImm, IDLoc, Instructions))
1914 MipsAsmParser::expandLoadAddressSym(const MCOperand &DstRegOp,
1915 const MCOperand &SymOp, SMLoc IDLoc,
1916 SmallVectorImpl<MCInst> &Instructions) {
1918 unsigned RegNo = DstRegOp.getReg();
1919 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1920 const MCSymbolRefExpr *HiExpr =
1921 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1922 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1923 const MCSymbolRefExpr *LoExpr =
1924 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1925 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1927 // If it's a 64-bit architecture, expand to:
1928 // la d,sym => lui d,highest(sym)
1929 // ori d,d,higher(sym)
1931 // ori d,d,hi16(sym)
1933 // ori d,d,lo16(sym)
1934 const MCSymbolRefExpr *HighestExpr =
1935 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1936 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1937 const MCSymbolRefExpr *HigherExpr =
1938 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1939 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1941 tmpInst.setOpcode(Mips::LUi);
1942 tmpInst.addOperand(MCOperand::createReg(RegNo));
1943 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1944 Instructions.push_back(tmpInst);
1946 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), RegNo, SMLoc(),
1948 createLShiftOri<16>(MCOperand::createExpr(HiExpr), RegNo, SMLoc(),
1950 createLShiftOri<16>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1953 // Otherwise, expand to:
1954 // la d,sym => lui d,hi16(sym)
1955 // ori d,d,lo16(sym)
1956 tmpInst.setOpcode(Mips::LUi);
1957 tmpInst.addOperand(MCOperand::createReg(RegNo));
1958 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
1959 Instructions.push_back(tmpInst);
1961 createLShiftOri<0>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1966 bool MipsAsmParser::expandUncondBranchMMPseudo(
1967 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1968 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1969 "unexpected number of operands");
1971 MCOperand Offset = Inst.getOperand(0);
1972 if (Offset.isExpr()) {
1974 Inst.setOpcode(Mips::BEQ_MM);
1975 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1976 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1977 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
1979 assert(Offset.isImm() && "expected immediate operand kind");
1980 if (isIntN(11, Offset.getImm())) {
1981 // If offset fits into 11 bits then this instruction becomes microMIPS
1982 // 16-bit unconditional branch instruction.
1983 Inst.setOpcode(Mips::B16_MM);
1985 if (!isIntN(17, Offset.getImm()))
1986 Error(IDLoc, "branch target out of range");
1987 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1988 Error(IDLoc, "branch to misaligned address");
1990 Inst.setOpcode(Mips::BEQ_MM);
1991 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1992 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1993 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
1996 Instructions.push_back(Inst);
1998 // If .set reorder is active, emit a NOP after the branch instruction.
1999 if (AssemblerOptions.back()->isReorder())
2000 createNop(true, IDLoc, Instructions);
2005 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2006 SmallVectorImpl<MCInst> &Instructions,
2007 bool isLoad, bool isImmOpnd) {
2008 const MCSymbolRefExpr *SR;
2010 unsigned ImmOffset, HiOffset, LoOffset;
2011 const MCExpr *ExprOffset;
2013 // 1st operand is either the source or destination register.
2014 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2015 unsigned RegOpNum = Inst.getOperand(0).getReg();
2016 // 2nd operand is the base register.
2017 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2018 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2019 // 3rd operand is either an immediate or expression.
2021 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2022 ImmOffset = Inst.getOperand(2).getImm();
2023 LoOffset = ImmOffset & 0x0000ffff;
2024 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2025 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2026 if (LoOffset & 0x8000)
2029 ExprOffset = Inst.getOperand(2).getExpr();
2030 // All instructions will have the same location.
2031 TempInst.setLoc(IDLoc);
2032 // These are some of the types of expansions we perform here:
2033 // 1) lw $8, sym => lui $8, %hi(sym)
2034 // lw $8, %lo(sym)($8)
2035 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2037 // lw $8, %lo(offset)($9)
2038 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2040 // lw $8, %lo(offset)($at)
2041 // 4) sw $8, sym => lui $at, %hi(sym)
2042 // sw $8, %lo(sym)($at)
2043 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2045 // sw $8, %lo(offset)($at)
2046 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2047 // ldc1 $f0, %lo(sym)($at)
2049 // For load instructions we can use the destination register as a temporary
2050 // if base and dst are different (examples 1 and 2) and if the base register
2051 // is general purpose otherwise we must use $at (example 6) and error if it's
2052 // not available. For stores we must use $at (examples 4 and 5) because we
2053 // must not clobber the source register setting up the offset.
2054 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2055 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2056 unsigned RegClassIDOp0 =
2057 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2058 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2059 (RegClassIDOp0 == Mips::GPR64RegClassID);
2060 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2061 TmpRegNum = RegOpNum;
2063 // At this point we need AT to perform the expansions and we exit if it is
2065 TmpRegNum = getATReg(IDLoc);
2070 TempInst.setOpcode(Mips::LUi);
2071 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2073 TempInst.addOperand(MCOperand::createImm(HiOffset));
2075 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2076 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2077 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2078 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2080 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2082 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2083 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2086 // Add the instruction to the list.
2087 Instructions.push_back(TempInst);
2088 // Prepare TempInst for next instruction.
2090 // Add temp register to base.
2091 if (BaseRegNum != Mips::ZERO) {
2092 TempInst.setOpcode(Mips::ADDu);
2093 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2094 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2095 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2096 Instructions.push_back(TempInst);
2099 // And finally, create original instruction with low part
2100 // of offset and new base.
2101 TempInst.setOpcode(Inst.getOpcode());
2102 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2103 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2105 TempInst.addOperand(MCOperand::createImm(LoOffset));
2107 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2108 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2109 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2111 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2113 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2114 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2117 Instructions.push_back(TempInst);
2122 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2123 SmallVectorImpl<MCInst> &Instructions) {
2124 unsigned OpNum = Inst.getNumOperands();
2125 unsigned Opcode = Inst.getOpcode();
2126 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2128 assert (Inst.getOperand(OpNum - 1).isImm() &&
2129 Inst.getOperand(OpNum - 2).isReg() &&
2130 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2132 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2133 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2134 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2135 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2136 // It can be implemented as SWM16 or LWM16 instruction.
2137 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2139 Inst.setOpcode(NewOpcode);
2140 Instructions.push_back(Inst);
2144 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2145 SmallVectorImpl<MCInst> &Instructions) {
2147 if (hasShortDelaySlot) {
2148 NopInst.setOpcode(Mips::MOVE16_MM);
2149 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2150 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2152 NopInst.setOpcode(Mips::SLL);
2153 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2154 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2155 NopInst.addOperand(MCOperand::createImm(0));
2157 Instructions.push_back(NopInst);
2160 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2162 SmallVectorImpl<MCInst> &Instructions) {
2164 AdduInst.setOpcode(Mips::ADDu);
2165 AdduInst.addOperand(MCOperand::createReg(DstReg));
2166 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2167 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2168 Instructions.push_back(AdduInst);
2171 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2172 // As described by the Mips32r2 spec, the registers Rd and Rs for
2173 // jalr.hb must be different.
2174 unsigned Opcode = Inst.getOpcode();
2176 if (Opcode == Mips::JALR_HB &&
2177 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2178 return Match_RequiresDifferentSrcAndDst;
2180 return Match_Success;
2183 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2184 OperandVector &Operands,
2186 uint64_t &ErrorInfo,
2187 bool MatchingInlineAsm) {
2190 SmallVector<MCInst, 8> Instructions;
2191 unsigned MatchResult =
2192 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2194 switch (MatchResult) {
2195 case Match_Success: {
2196 if (processInstruction(Inst, IDLoc, Instructions))
2198 for (unsigned i = 0; i < Instructions.size(); i++)
2199 Out.EmitInstruction(Instructions[i], STI);
2202 case Match_MissingFeature:
2203 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2205 case Match_InvalidOperand: {
2206 SMLoc ErrorLoc = IDLoc;
2207 if (ErrorInfo != ~0ULL) {
2208 if (ErrorInfo >= Operands.size())
2209 return Error(IDLoc, "too few operands for instruction");
2211 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2212 if (ErrorLoc == SMLoc())
2216 return Error(ErrorLoc, "invalid operand for instruction");
2218 case Match_MnemonicFail:
2219 return Error(IDLoc, "invalid instruction");
2220 case Match_RequiresDifferentSrcAndDst:
2221 return Error(IDLoc, "source and destination must be different");
2224 llvm_unreachable("Implement any new match types added!");
2227 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2228 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2229 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2230 ") without \".set noat\"");
2234 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2235 SMRange Range, bool ShowColors) {
2236 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2237 Range, SMFixIt(Range, FixMsg),
2241 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2244 CC = StringSwitch<unsigned>(Name)
2280 if (!(isABI_N32() || isABI_N64()))
2283 if (12 <= CC && CC <= 15) {
2284 // Name is one of t4-t7
2285 AsmToken RegTok = getLexer().peekTok();
2286 SMRange RegRange = RegTok.getLocRange();
2288 StringRef FixedName = StringSwitch<StringRef>(Name)
2294 assert(FixedName != "" && "Register name is not one of t4-t7.");
2296 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2297 "Did you mean $" + FixedName + "?", RegRange);
2300 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2301 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2302 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2303 if (8 <= CC && CC <= 11)
2307 CC = StringSwitch<unsigned>(Name)
2319 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2322 CC = StringSwitch<unsigned>(Name)
2323 .Case("hwr_cpunum", 0)
2324 .Case("hwr_synci_step", 1)
2326 .Case("hwr_ccres", 3)
2327 .Case("hwr_ulr", 29)
2333 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2335 if (Name[0] == 'f') {
2336 StringRef NumString = Name.substr(1);
2338 if (NumString.getAsInteger(10, IntVal))
2339 return -1; // This is not an integer.
2340 if (IntVal > 31) // Maximum index for fpu register.
2347 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2349 if (Name.startswith("fcc")) {
2350 StringRef NumString = Name.substr(3);
2352 if (NumString.getAsInteger(10, IntVal))
2353 return -1; // This is not an integer.
2354 if (IntVal > 7) // There are only 8 fcc registers.
2361 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2363 if (Name.startswith("ac")) {
2364 StringRef NumString = Name.substr(2);
2366 if (NumString.getAsInteger(10, IntVal))
2367 return -1; // This is not an integer.
2368 if (IntVal > 3) // There are only 3 acc registers.
2375 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2378 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2387 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2390 CC = StringSwitch<unsigned>(Name)
2393 .Case("msaaccess", 2)
2395 .Case("msamodify", 4)
2396 .Case("msarequest", 5)
2398 .Case("msaunmap", 7)
2404 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2405 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2407 reportParseError(Loc,
2408 "pseudo-instruction requires $at, which is not available");
2411 unsigned AT = getReg(
2412 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2416 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2417 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2420 unsigned MipsAsmParser::getGPR(int RegNo) {
2421 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2425 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2427 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2430 return getReg(RegClass, RegNum);
2433 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2434 MCAsmParser &Parser = getParser();
2435 DEBUG(dbgs() << "parseOperand\n");
2437 // Check if the current operand has a custom associated parser, if so, try to
2438 // custom parse the operand, or fallback to the general approach.
2439 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2440 if (ResTy == MatchOperand_Success)
2442 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2443 // there was a match, but an error occurred, in which case, just return that
2444 // the operand parsing failed.
2445 if (ResTy == MatchOperand_ParseFail)
2448 DEBUG(dbgs() << ".. Generic Parser\n");
2450 switch (getLexer().getKind()) {
2452 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2454 case AsmToken::Dollar: {
2455 // Parse the register.
2456 SMLoc S = Parser.getTok().getLoc();
2458 // Almost all registers have been parsed by custom parsers. There is only
2459 // one exception to this. $zero (and it's alias $0) will reach this point
2460 // for div, divu, and similar instructions because it is not an operand
2461 // to the instruction definition but an explicit register. Special case
2462 // this situation for now.
2463 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2466 // Maybe it is a symbol reference.
2467 StringRef Identifier;
2468 if (Parser.parseIdentifier(Identifier))
2471 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2472 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2473 // Otherwise create a symbol reference.
2475 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2477 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2480 // Else drop to expression parsing.
2481 case AsmToken::LParen:
2482 case AsmToken::Minus:
2483 case AsmToken::Plus:
2484 case AsmToken::Integer:
2485 case AsmToken::Tilde:
2486 case AsmToken::String: {
2487 DEBUG(dbgs() << ".. generic integer\n");
2488 OperandMatchResultTy ResTy = parseImm(Operands);
2489 return ResTy != MatchOperand_Success;
2491 case AsmToken::Percent: {
2492 // It is a symbol reference or constant expression.
2493 const MCExpr *IdVal;
2494 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2495 if (parseRelocOperand(IdVal))
2498 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2500 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2502 } // case AsmToken::Percent
2503 } // switch(getLexer().getKind())
2507 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2508 StringRef RelocStr) {
2510 // Check the type of the expression.
2511 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2512 // It's a constant, evaluate reloc value.
2514 switch (getVariantKind(RelocStr)) {
2515 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2516 // Get the 1st 16-bits.
2517 Val = MCE->getValue() & 0xffff;
2519 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2520 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2521 // 16 bits being negative.
2522 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2524 case MCSymbolRefExpr::VK_Mips_HIGHER:
2525 // Get the 3rd 16-bits.
2526 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2528 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2529 // Get the 4th 16-bits.
2530 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2533 report_fatal_error("unsupported reloc value");
2535 return MCConstantExpr::Create(Val, getContext());
2538 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2539 // It's a symbol, create a symbolic expression from the symbol.
2540 StringRef Symbol = MSRE->getSymbol().getName();
2541 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2542 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2546 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2547 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2549 // Try to create target expression.
2550 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2551 return MipsMCExpr::Create(VK, Expr, getContext());
2553 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2554 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2555 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2559 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2560 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2561 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2564 // Just return the original expression.
2568 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2570 switch (Expr->getKind()) {
2571 case MCExpr::Constant:
2573 case MCExpr::SymbolRef:
2574 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2575 case MCExpr::Binary:
2576 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2577 if (!isEvaluated(BE->getLHS()))
2579 return isEvaluated(BE->getRHS());
2582 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2583 case MCExpr::Target:
2589 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2590 MCAsmParser &Parser = getParser();
2591 Parser.Lex(); // Eat the % token.
2592 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2593 if (Tok.isNot(AsmToken::Identifier))
2596 std::string Str = Tok.getIdentifier();
2598 Parser.Lex(); // Eat the identifier.
2599 // Now make an expression from the rest of the operand.
2600 const MCExpr *IdVal;
2603 if (getLexer().getKind() == AsmToken::LParen) {
2605 Parser.Lex(); // Eat the '(' token.
2606 if (getLexer().getKind() == AsmToken::Percent) {
2607 Parser.Lex(); // Eat the % token.
2608 const AsmToken &nextTok = Parser.getTok();
2609 if (nextTok.isNot(AsmToken::Identifier))
2612 Str += nextTok.getIdentifier();
2613 Parser.Lex(); // Eat the identifier.
2614 if (getLexer().getKind() != AsmToken::LParen)
2619 if (getParser().parseParenExpression(IdVal, EndLoc))
2622 while (getLexer().getKind() == AsmToken::RParen)
2623 Parser.Lex(); // Eat the ')' token.
2626 return true; // Parenthesis must follow the relocation operand.
2628 Res = evaluateRelocExpr(IdVal, Str);
2632 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2634 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2635 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2636 if (ResTy == MatchOperand_Success) {
2637 assert(Operands.size() == 1);
2638 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2639 StartLoc = Operand.getStartLoc();
2640 EndLoc = Operand.getEndLoc();
2642 // AFAIK, we only support numeric registers and named GPR's in CFI
2644 // Don't worry about eating tokens before failing. Using an unrecognised
2645 // register is a parse error.
2646 if (Operand.isGPRAsmReg()) {
2647 // Resolve to GPR32 or GPR64 appropriately.
2648 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2651 return (RegNo == (unsigned)-1);
2654 assert(Operands.size() == 0);
2655 return (RegNo == (unsigned)-1);
2658 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2659 MCAsmParser &Parser = getParser();
2663 while (getLexer().getKind() == AsmToken::LParen)
2666 switch (getLexer().getKind()) {
2669 case AsmToken::Identifier:
2670 case AsmToken::LParen:
2671 case AsmToken::Integer:
2672 case AsmToken::Minus:
2673 case AsmToken::Plus:
2675 Result = getParser().parseParenExpression(Res, S);
2677 Result = (getParser().parseExpression(Res));
2678 while (getLexer().getKind() == AsmToken::RParen)
2681 case AsmToken::Percent:
2682 Result = parseRelocOperand(Res);
2687 MipsAsmParser::OperandMatchResultTy
2688 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2689 MCAsmParser &Parser = getParser();
2690 DEBUG(dbgs() << "parseMemOperand\n");
2691 const MCExpr *IdVal = nullptr;
2693 bool isParenExpr = false;
2694 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2695 // First operand is the offset.
2696 S = Parser.getTok().getLoc();
2698 if (getLexer().getKind() == AsmToken::LParen) {
2703 if (getLexer().getKind() != AsmToken::Dollar) {
2704 if (parseMemOffset(IdVal, isParenExpr))
2705 return MatchOperand_ParseFail;
2707 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2708 if (Tok.isNot(AsmToken::LParen)) {
2709 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2710 if (Mnemonic.getToken() == "la") {
2712 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2713 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2714 return MatchOperand_Success;
2716 if (Tok.is(AsmToken::EndOfStatement)) {
2718 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2720 // Zero register assumed, add a memory operand with ZERO as its base.
2721 // "Base" will be managed by k_Memory.
2722 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2725 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2726 return MatchOperand_Success;
2728 Error(Parser.getTok().getLoc(), "'(' expected");
2729 return MatchOperand_ParseFail;
2732 Parser.Lex(); // Eat the '(' token.
2735 Res = parseAnyRegister(Operands);
2736 if (Res != MatchOperand_Success)
2739 if (Parser.getTok().isNot(AsmToken::RParen)) {
2740 Error(Parser.getTok().getLoc(), "')' expected");
2741 return MatchOperand_ParseFail;
2744 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2746 Parser.Lex(); // Eat the ')' token.
2749 IdVal = MCConstantExpr::Create(0, getContext());
2751 // Replace the register operand with the memory operand.
2752 std::unique_ptr<MipsOperand> op(
2753 static_cast<MipsOperand *>(Operands.back().release()));
2754 // Remove the register from the operands.
2755 // "op" will be managed by k_Memory.
2756 Operands.pop_back();
2757 // Add the memory operand.
2758 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2760 if (IdVal->EvaluateAsAbsolute(Imm))
2761 IdVal = MCConstantExpr::Create(Imm, getContext());
2762 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2763 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2767 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2768 return MatchOperand_Success;
2771 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2772 MCAsmParser &Parser = getParser();
2773 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2775 SMLoc S = Parser.getTok().getLoc();
2777 if (Sym->isVariable())
2778 Expr = Sym->getVariableValue();
2781 if (Expr->getKind() == MCExpr::SymbolRef) {
2782 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2783 StringRef DefSymbol = Ref->getSymbol().getName();
2784 if (DefSymbol.startswith("$")) {
2785 OperandMatchResultTy ResTy =
2786 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2787 if (ResTy == MatchOperand_Success) {
2790 } else if (ResTy == MatchOperand_ParseFail)
2791 llvm_unreachable("Should never ParseFail");
2794 } else if (Expr->getKind() == MCExpr::Constant) {
2796 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2798 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2805 MipsAsmParser::OperandMatchResultTy
2806 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2807 StringRef Identifier,
2809 int Index = matchCPURegisterName(Identifier);
2811 Operands.push_back(MipsOperand::createGPRReg(
2812 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2813 return MatchOperand_Success;
2816 Index = matchHWRegsRegisterName(Identifier);
2818 Operands.push_back(MipsOperand::createHWRegsReg(
2819 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2820 return MatchOperand_Success;
2823 Index = matchFPURegisterName(Identifier);
2825 Operands.push_back(MipsOperand::createFGRReg(
2826 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2827 return MatchOperand_Success;
2830 Index = matchFCCRegisterName(Identifier);
2832 Operands.push_back(MipsOperand::createFCCReg(
2833 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2834 return MatchOperand_Success;
2837 Index = matchACRegisterName(Identifier);
2839 Operands.push_back(MipsOperand::createACCReg(
2840 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2841 return MatchOperand_Success;
2844 Index = matchMSA128RegisterName(Identifier);
2846 Operands.push_back(MipsOperand::createMSA128Reg(
2847 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2848 return MatchOperand_Success;
2851 Index = matchMSA128CtrlRegisterName(Identifier);
2853 Operands.push_back(MipsOperand::createMSACtrlReg(
2854 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2855 return MatchOperand_Success;
2858 return MatchOperand_NoMatch;
2861 MipsAsmParser::OperandMatchResultTy
2862 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2863 MCAsmParser &Parser = getParser();
2864 auto Token = Parser.getLexer().peekTok(false);
2866 if (Token.is(AsmToken::Identifier)) {
2867 DEBUG(dbgs() << ".. identifier\n");
2868 StringRef Identifier = Token.getIdentifier();
2869 OperandMatchResultTy ResTy =
2870 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2872 } else if (Token.is(AsmToken::Integer)) {
2873 DEBUG(dbgs() << ".. integer\n");
2874 Operands.push_back(MipsOperand::createNumericReg(
2875 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2877 return MatchOperand_Success;
2880 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2882 return MatchOperand_NoMatch;
2885 MipsAsmParser::OperandMatchResultTy
2886 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2887 MCAsmParser &Parser = getParser();
2888 DEBUG(dbgs() << "parseAnyRegister\n");
2890 auto Token = Parser.getTok();
2892 SMLoc S = Token.getLoc();
2894 if (Token.isNot(AsmToken::Dollar)) {
2895 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2896 if (Token.is(AsmToken::Identifier)) {
2897 if (searchSymbolAlias(Operands))
2898 return MatchOperand_Success;
2900 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2901 return MatchOperand_NoMatch;
2903 DEBUG(dbgs() << ".. $\n");
2905 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2906 if (ResTy == MatchOperand_Success) {
2908 Parser.Lex(); // identifier
2913 MipsAsmParser::OperandMatchResultTy
2914 MipsAsmParser::parseImm(OperandVector &Operands) {
2915 MCAsmParser &Parser = getParser();
2916 switch (getLexer().getKind()) {
2918 return MatchOperand_NoMatch;
2919 case AsmToken::LParen:
2920 case AsmToken::Minus:
2921 case AsmToken::Plus:
2922 case AsmToken::Integer:
2923 case AsmToken::Tilde:
2924 case AsmToken::String:
2928 const MCExpr *IdVal;
2929 SMLoc S = Parser.getTok().getLoc();
2930 if (getParser().parseExpression(IdVal))
2931 return MatchOperand_ParseFail;
2933 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2934 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2935 return MatchOperand_Success;
2938 MipsAsmParser::OperandMatchResultTy
2939 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2940 MCAsmParser &Parser = getParser();
2941 DEBUG(dbgs() << "parseJumpTarget\n");
2943 SMLoc S = getLexer().getLoc();
2945 // Integers and expressions are acceptable
2946 OperandMatchResultTy ResTy = parseImm(Operands);
2947 if (ResTy != MatchOperand_NoMatch)
2950 // Registers are a valid target and have priority over symbols.
2951 ResTy = parseAnyRegister(Operands);
2952 if (ResTy != MatchOperand_NoMatch)
2955 const MCExpr *Expr = nullptr;
2956 if (Parser.parseExpression(Expr)) {
2957 // We have no way of knowing if a symbol was consumed so we must ParseFail
2958 return MatchOperand_ParseFail;
2961 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2962 return MatchOperand_Success;
2965 MipsAsmParser::OperandMatchResultTy
2966 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2967 MCAsmParser &Parser = getParser();
2968 const MCExpr *IdVal;
2969 // If the first token is '$' we may have register operand.
2970 if (Parser.getTok().is(AsmToken::Dollar))
2971 return MatchOperand_NoMatch;
2972 SMLoc S = Parser.getTok().getLoc();
2973 if (getParser().parseExpression(IdVal))
2974 return MatchOperand_ParseFail;
2975 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2976 assert(MCE && "Unexpected MCExpr type.");
2977 int64_t Val = MCE->getValue();
2978 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2979 Operands.push_back(MipsOperand::CreateImm(
2980 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2981 return MatchOperand_Success;
2984 MipsAsmParser::OperandMatchResultTy
2985 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2986 MCAsmParser &Parser = getParser();
2987 switch (getLexer().getKind()) {
2989 return MatchOperand_NoMatch;
2990 case AsmToken::LParen:
2991 case AsmToken::Plus:
2992 case AsmToken::Minus:
2993 case AsmToken::Integer:
2998 SMLoc S = Parser.getTok().getLoc();
3000 if (getParser().parseExpression(Expr))
3001 return MatchOperand_ParseFail;
3004 if (!Expr->EvaluateAsAbsolute(Val)) {
3005 Error(S, "expected immediate value");
3006 return MatchOperand_ParseFail;
3009 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3010 // and because the CPU always adds one to the immediate field, the allowed
3011 // range becomes 1..4. We'll only check the range here and will deal
3012 // with the addition/subtraction when actually decoding/encoding
3014 if (Val < 1 || Val > 4) {
3015 Error(S, "immediate not in range (1..4)");
3016 return MatchOperand_ParseFail;
3020 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3021 return MatchOperand_Success;
3024 MipsAsmParser::OperandMatchResultTy
3025 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3026 MCAsmParser &Parser = getParser();
3027 SmallVector<unsigned, 10> Regs;
3029 unsigned PrevReg = Mips::NoRegister;
3030 bool RegRange = false;
3031 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3033 if (Parser.getTok().isNot(AsmToken::Dollar))
3034 return MatchOperand_ParseFail;
3036 SMLoc S = Parser.getTok().getLoc();
3037 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3038 SMLoc E = getLexer().getLoc();
3039 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3040 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3042 // Remove last register operand because registers from register range
3043 // should be inserted first.
3044 if (RegNo == Mips::RA) {
3045 Regs.push_back(RegNo);
3047 unsigned TmpReg = PrevReg + 1;
3048 while (TmpReg <= RegNo) {
3049 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3050 Error(E, "invalid register operand");
3051 return MatchOperand_ParseFail;
3055 Regs.push_back(TmpReg++);
3061 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3062 (RegNo != Mips::RA)) {
3063 Error(E, "$16 or $31 expected");
3064 return MatchOperand_ParseFail;
3065 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3066 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3067 Error(E, "invalid register operand");
3068 return MatchOperand_ParseFail;
3069 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3070 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3071 Error(E, "consecutive register numbers expected");
3072 return MatchOperand_ParseFail;
3075 Regs.push_back(RegNo);
3078 if (Parser.getTok().is(AsmToken::Minus))
3081 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3082 !Parser.getTok().isNot(AsmToken::Comma)) {
3083 Error(E, "',' or '-' expected");
3084 return MatchOperand_ParseFail;
3087 Lex(); // Consume comma or minus
3088 if (Parser.getTok().isNot(AsmToken::Dollar))
3094 SMLoc E = Parser.getTok().getLoc();
3095 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3096 parseMemOperand(Operands);
3097 return MatchOperand_Success;
3100 MipsAsmParser::OperandMatchResultTy
3101 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3102 MCAsmParser &Parser = getParser();
3104 SMLoc S = Parser.getTok().getLoc();
3105 if (parseAnyRegister(Operands) != MatchOperand_Success)
3106 return MatchOperand_ParseFail;
3108 SMLoc E = Parser.getTok().getLoc();
3109 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3110 unsigned Reg = Op.getGPR32Reg();
3111 Operands.pop_back();
3112 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3113 return MatchOperand_Success;
3116 MipsAsmParser::OperandMatchResultTy
3117 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3118 MCAsmParser &Parser = getParser();
3119 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3120 SmallVector<unsigned, 10> Regs;
3122 if (Parser.getTok().isNot(AsmToken::Dollar))
3123 return MatchOperand_ParseFail;
3125 SMLoc S = Parser.getTok().getLoc();
3127 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3128 return MatchOperand_ParseFail;
3130 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3131 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3132 Regs.push_back(RegNo);
3134 SMLoc E = Parser.getTok().getLoc();
3135 if (Parser.getTok().isNot(AsmToken::Comma)) {
3136 Error(E, "',' expected");
3137 return MatchOperand_ParseFail;
3143 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3144 return MatchOperand_ParseFail;
3146 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3147 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3148 Regs.push_back(RegNo);
3150 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3152 return MatchOperand_Success;
3155 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3157 MCSymbolRefExpr::VariantKind VK =
3158 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3159 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3160 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3161 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3162 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3163 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3164 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3165 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3166 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3167 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3168 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3169 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3170 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3171 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3172 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3173 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3174 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3175 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3176 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3177 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3178 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3179 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3180 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3181 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3182 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3183 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3184 .Default(MCSymbolRefExpr::VK_None);
3186 assert(VK != MCSymbolRefExpr::VK_None);
3191 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3193 /// ::= '(', register, ')'
3194 /// handle it before we iterate so we don't get tripped up by the lack of
3196 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3197 MCAsmParser &Parser = getParser();
3198 if (getLexer().is(AsmToken::LParen)) {
3200 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3202 if (parseOperand(Operands, Name)) {
3203 SMLoc Loc = getLexer().getLoc();
3204 Parser.eatToEndOfStatement();
3205 return Error(Loc, "unexpected token in argument list");
3207 if (Parser.getTok().isNot(AsmToken::RParen)) {
3208 SMLoc Loc = getLexer().getLoc();
3209 Parser.eatToEndOfStatement();
3210 return Error(Loc, "unexpected token, expected ')'");
3213 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3219 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3220 /// either one of these.
3221 /// ::= '[', register, ']'
3222 /// ::= '[', integer, ']'
3223 /// handle it before we iterate so we don't get tripped up by the lack of
3225 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3226 OperandVector &Operands) {
3227 MCAsmParser &Parser = getParser();
3228 if (getLexer().is(AsmToken::LBrac)) {
3230 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3232 if (parseOperand(Operands, Name)) {
3233 SMLoc Loc = getLexer().getLoc();
3234 Parser.eatToEndOfStatement();
3235 return Error(Loc, "unexpected token in argument list");
3237 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3238 SMLoc Loc = getLexer().getLoc();
3239 Parser.eatToEndOfStatement();
3240 return Error(Loc, "unexpected token, expected ']'");
3243 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3249 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3250 SMLoc NameLoc, OperandVector &Operands) {
3251 MCAsmParser &Parser = getParser();
3252 DEBUG(dbgs() << "ParseInstruction\n");
3254 // We have reached first instruction, module directive are now forbidden.
3255 getTargetStreamer().forbidModuleDirective();
3257 // Check if we have valid mnemonic
3258 if (!mnemonicIsValid(Name, 0)) {
3259 Parser.eatToEndOfStatement();
3260 return Error(NameLoc, "unknown instruction");
3262 // First operand in MCInst is instruction mnemonic.
3263 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3265 // Read the remaining operands.
3266 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3267 // Read the first operand.
3268 if (parseOperand(Operands, Name)) {
3269 SMLoc Loc = getLexer().getLoc();
3270 Parser.eatToEndOfStatement();
3271 return Error(Loc, "unexpected token in argument list");
3273 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3275 // AFAIK, parenthesis suffixes are never on the first operand
3277 while (getLexer().is(AsmToken::Comma)) {
3278 Parser.Lex(); // Eat the comma.
3279 // Parse and remember the operand.
3280 if (parseOperand(Operands, Name)) {
3281 SMLoc Loc = getLexer().getLoc();
3282 Parser.eatToEndOfStatement();
3283 return Error(Loc, "unexpected token in argument list");
3285 // Parse bracket and parenthesis suffixes before we iterate
3286 if (getLexer().is(AsmToken::LBrac)) {
3287 if (parseBracketSuffix(Name, Operands))
3289 } else if (getLexer().is(AsmToken::LParen) &&
3290 parseParenSuffix(Name, Operands))
3294 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3295 SMLoc Loc = getLexer().getLoc();
3296 Parser.eatToEndOfStatement();
3297 return Error(Loc, "unexpected token in argument list");
3299 Parser.Lex(); // Consume the EndOfStatement.
3303 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3304 MCAsmParser &Parser = getParser();
3305 SMLoc Loc = getLexer().getLoc();
3306 Parser.eatToEndOfStatement();
3307 return Error(Loc, ErrorMsg);
3310 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3311 return Error(Loc, ErrorMsg);
3314 bool MipsAsmParser::parseSetNoAtDirective() {
3315 MCAsmParser &Parser = getParser();
3316 // Line should look like: ".set noat".
3318 // Set the $at register to $0.
3319 AssemblerOptions.back()->setATRegIndex(0);
3321 Parser.Lex(); // Eat "noat".
3323 // If this is not the end of the statement, report an error.
3324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3325 reportParseError("unexpected token, expected end of statement");
3329 getTargetStreamer().emitDirectiveSetNoAt();
3330 Parser.Lex(); // Consume the EndOfStatement.
3334 bool MipsAsmParser::parseSetAtDirective() {
3335 // Line can be: ".set at", which sets $at to $1
3336 // or ".set at=$reg", which sets $at to $reg.
3337 MCAsmParser &Parser = getParser();
3338 Parser.Lex(); // Eat "at".
3340 if (getLexer().is(AsmToken::EndOfStatement)) {
3341 // No register was specified, so we set $at to $1.
3342 AssemblerOptions.back()->setATRegIndex(1);
3344 getTargetStreamer().emitDirectiveSetAt();
3345 Parser.Lex(); // Consume the EndOfStatement.
3349 if (getLexer().isNot(AsmToken::Equal)) {
3350 reportParseError("unexpected token, expected equals sign");
3353 Parser.Lex(); // Eat "=".
3355 if (getLexer().isNot(AsmToken::Dollar)) {
3356 if (getLexer().is(AsmToken::EndOfStatement)) {
3357 reportParseError("no register specified");
3360 reportParseError("unexpected token, expected dollar sign '$'");
3364 Parser.Lex(); // Eat "$".
3366 // Find out what "reg" is.
3368 const AsmToken &Reg = Parser.getTok();
3369 if (Reg.is(AsmToken::Identifier)) {
3370 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3371 } else if (Reg.is(AsmToken::Integer)) {
3372 AtRegNo = Reg.getIntVal();
3374 reportParseError("unexpected token, expected identifier or integer");
3378 // Check if $reg is a valid register. If it is, set $at to $reg.
3379 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3380 reportParseError("invalid register");
3383 Parser.Lex(); // Eat "reg".
3385 // If this is not the end of the statement, report an error.
3386 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3387 reportParseError("unexpected token, expected end of statement");
3391 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3393 Parser.Lex(); // Consume the EndOfStatement.
3397 bool MipsAsmParser::parseSetReorderDirective() {
3398 MCAsmParser &Parser = getParser();
3400 // If this is not the end of the statement, report an error.
3401 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3402 reportParseError("unexpected token, expected end of statement");
3405 AssemblerOptions.back()->setReorder();
3406 getTargetStreamer().emitDirectiveSetReorder();
3407 Parser.Lex(); // Consume the EndOfStatement.
3411 bool MipsAsmParser::parseSetNoReorderDirective() {
3412 MCAsmParser &Parser = getParser();
3414 // If this is not the end of the statement, report an error.
3415 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3416 reportParseError("unexpected token, expected end of statement");
3419 AssemblerOptions.back()->setNoReorder();
3420 getTargetStreamer().emitDirectiveSetNoReorder();
3421 Parser.Lex(); // Consume the EndOfStatement.
3425 bool MipsAsmParser::parseSetMacroDirective() {
3426 MCAsmParser &Parser = getParser();
3428 // If this is not the end of the statement, report an error.
3429 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3430 reportParseError("unexpected token, expected end of statement");
3433 AssemblerOptions.back()->setMacro();
3434 Parser.Lex(); // Consume the EndOfStatement.
3438 bool MipsAsmParser::parseSetNoMacroDirective() {
3439 MCAsmParser &Parser = getParser();
3441 // If this is not the end of the statement, report an error.
3442 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3443 reportParseError("unexpected token, expected end of statement");
3446 if (AssemblerOptions.back()->isReorder()) {
3447 reportParseError("`noreorder' must be set before `nomacro'");
3450 AssemblerOptions.back()->setNoMacro();
3451 Parser.Lex(); // Consume the EndOfStatement.
3455 bool MipsAsmParser::parseSetMsaDirective() {
3456 MCAsmParser &Parser = getParser();
3459 // If this is not the end of the statement, report an error.
3460 if (getLexer().isNot(AsmToken::EndOfStatement))
3461 return reportParseError("unexpected token, expected end of statement");
3463 setFeatureBits(Mips::FeatureMSA, "msa");
3464 getTargetStreamer().emitDirectiveSetMsa();
3468 bool MipsAsmParser::parseSetNoMsaDirective() {
3469 MCAsmParser &Parser = getParser();
3472 // If this is not the end of the statement, report an error.
3473 if (getLexer().isNot(AsmToken::EndOfStatement))
3474 return reportParseError("unexpected token, expected end of statement");
3476 clearFeatureBits(Mips::FeatureMSA, "msa");
3477 getTargetStreamer().emitDirectiveSetNoMsa();
3481 bool MipsAsmParser::parseSetNoDspDirective() {
3482 MCAsmParser &Parser = getParser();
3483 Parser.Lex(); // Eat "nodsp".
3485 // If this is not the end of the statement, report an error.
3486 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3487 reportParseError("unexpected token, expected end of statement");
3491 clearFeatureBits(Mips::FeatureDSP, "dsp");
3492 getTargetStreamer().emitDirectiveSetNoDsp();
3496 bool MipsAsmParser::parseSetMips16Directive() {
3497 MCAsmParser &Parser = getParser();
3498 Parser.Lex(); // Eat "mips16".
3500 // If this is not the end of the statement, report an error.
3501 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3502 reportParseError("unexpected token, expected end of statement");
3506 setFeatureBits(Mips::FeatureMips16, "mips16");
3507 getTargetStreamer().emitDirectiveSetMips16();
3508 Parser.Lex(); // Consume the EndOfStatement.
3512 bool MipsAsmParser::parseSetNoMips16Directive() {
3513 MCAsmParser &Parser = getParser();
3514 Parser.Lex(); // Eat "nomips16".
3516 // If this is not the end of the statement, report an error.
3517 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3518 reportParseError("unexpected token, expected end of statement");
3522 clearFeatureBits(Mips::FeatureMips16, "mips16");
3523 getTargetStreamer().emitDirectiveSetNoMips16();
3524 Parser.Lex(); // Consume the EndOfStatement.
3528 bool MipsAsmParser::parseSetFpDirective() {
3529 MCAsmParser &Parser = getParser();
3530 MipsABIFlagsSection::FpABIKind FpAbiVal;
3531 // Line can be: .set fp=32
3534 Parser.Lex(); // Eat fp token
3535 AsmToken Tok = Parser.getTok();
3536 if (Tok.isNot(AsmToken::Equal)) {
3537 reportParseError("unexpected token, expected equals sign '='");
3540 Parser.Lex(); // Eat '=' token.
3541 Tok = Parser.getTok();
3543 if (!parseFpABIValue(FpAbiVal, ".set"))
3546 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3547 reportParseError("unexpected token, expected end of statement");
3550 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3551 Parser.Lex(); // Consume the EndOfStatement.
3555 bool MipsAsmParser::parseSetPopDirective() {
3556 MCAsmParser &Parser = getParser();
3557 SMLoc Loc = getLexer().getLoc();
3560 if (getLexer().isNot(AsmToken::EndOfStatement))
3561 return reportParseError("unexpected token, expected end of statement");
3563 // Always keep an element on the options "stack" to prevent the user
3564 // from changing the initial options. This is how we remember them.
3565 if (AssemblerOptions.size() == 2)
3566 return reportParseError(Loc, ".set pop with no .set push");
3568 AssemblerOptions.pop_back();
3569 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3571 getTargetStreamer().emitDirectiveSetPop();
3575 bool MipsAsmParser::parseSetPushDirective() {
3576 MCAsmParser &Parser = getParser();
3578 if (getLexer().isNot(AsmToken::EndOfStatement))
3579 return reportParseError("unexpected token, expected end of statement");
3581 // Create a copy of the current assembler options environment and push it.
3582 AssemblerOptions.push_back(
3583 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3585 getTargetStreamer().emitDirectiveSetPush();
3589 bool MipsAsmParser::parseSetAssignment() {
3591 const MCExpr *Value;
3592 MCAsmParser &Parser = getParser();
3594 if (Parser.parseIdentifier(Name))
3595 reportParseError("expected identifier after .set");
3597 if (getLexer().isNot(AsmToken::Comma))
3598 return reportParseError("unexpected token, expected comma");
3601 if (Parser.parseExpression(Value))
3602 return reportParseError("expected valid expression after comma");
3604 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3605 Sym->setVariableValue(Value);
3610 bool MipsAsmParser::parseSetMips0Directive() {
3611 MCAsmParser &Parser = getParser();
3613 if (getLexer().isNot(AsmToken::EndOfStatement))
3614 return reportParseError("unexpected token, expected end of statement");
3616 // Reset assembler options to their initial values.
3617 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3618 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3620 getTargetStreamer().emitDirectiveSetMips0();
3624 bool MipsAsmParser::parseSetArchDirective() {
3625 MCAsmParser &Parser = getParser();
3627 if (getLexer().isNot(AsmToken::Equal))
3628 return reportParseError("unexpected token, expected equals sign");
3632 if (Parser.parseIdentifier(Arch))
3633 return reportParseError("expected arch identifier");
3635 StringRef ArchFeatureName =
3636 StringSwitch<StringRef>(Arch)
3637 .Case("mips1", "mips1")
3638 .Case("mips2", "mips2")
3639 .Case("mips3", "mips3")
3640 .Case("mips4", "mips4")
3641 .Case("mips5", "mips5")
3642 .Case("mips32", "mips32")
3643 .Case("mips32r2", "mips32r2")
3644 .Case("mips32r3", "mips32r3")
3645 .Case("mips32r5", "mips32r5")
3646 .Case("mips32r6", "mips32r6")
3647 .Case("mips64", "mips64")
3648 .Case("mips64r2", "mips64r2")
3649 .Case("mips64r3", "mips64r3")
3650 .Case("mips64r5", "mips64r5")
3651 .Case("mips64r6", "mips64r6")
3652 .Case("cnmips", "cnmips")
3653 .Case("r4000", "mips3") // This is an implementation of Mips3.
3656 if (ArchFeatureName.empty())
3657 return reportParseError("unsupported architecture");
3659 selectArch(ArchFeatureName);
3660 getTargetStreamer().emitDirectiveSetArch(Arch);
3664 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3665 MCAsmParser &Parser = getParser();
3667 if (getLexer().isNot(AsmToken::EndOfStatement))
3668 return reportParseError("unexpected token, expected end of statement");
3672 llvm_unreachable("Unimplemented feature");
3673 case Mips::FeatureDSP:
3674 setFeatureBits(Mips::FeatureDSP, "dsp");
3675 getTargetStreamer().emitDirectiveSetDsp();
3677 case Mips::FeatureMicroMips:
3678 getTargetStreamer().emitDirectiveSetMicroMips();
3680 case Mips::FeatureMips1:
3681 selectArch("mips1");
3682 getTargetStreamer().emitDirectiveSetMips1();
3684 case Mips::FeatureMips2:
3685 selectArch("mips2");
3686 getTargetStreamer().emitDirectiveSetMips2();
3688 case Mips::FeatureMips3:
3689 selectArch("mips3");
3690 getTargetStreamer().emitDirectiveSetMips3();
3692 case Mips::FeatureMips4:
3693 selectArch("mips4");
3694 getTargetStreamer().emitDirectiveSetMips4();
3696 case Mips::FeatureMips5:
3697 selectArch("mips5");
3698 getTargetStreamer().emitDirectiveSetMips5();
3700 case Mips::FeatureMips32:
3701 selectArch("mips32");
3702 getTargetStreamer().emitDirectiveSetMips32();
3704 case Mips::FeatureMips32r2:
3705 selectArch("mips32r2");
3706 getTargetStreamer().emitDirectiveSetMips32R2();
3708 case Mips::FeatureMips32r3:
3709 selectArch("mips32r3");
3710 getTargetStreamer().emitDirectiveSetMips32R3();
3712 case Mips::FeatureMips32r5:
3713 selectArch("mips32r5");
3714 getTargetStreamer().emitDirectiveSetMips32R5();
3716 case Mips::FeatureMips32r6:
3717 selectArch("mips32r6");
3718 getTargetStreamer().emitDirectiveSetMips32R6();
3720 case Mips::FeatureMips64:
3721 selectArch("mips64");
3722 getTargetStreamer().emitDirectiveSetMips64();
3724 case Mips::FeatureMips64r2:
3725 selectArch("mips64r2");
3726 getTargetStreamer().emitDirectiveSetMips64R2();
3728 case Mips::FeatureMips64r3:
3729 selectArch("mips64r3");
3730 getTargetStreamer().emitDirectiveSetMips64R3();
3732 case Mips::FeatureMips64r5:
3733 selectArch("mips64r5");
3734 getTargetStreamer().emitDirectiveSetMips64R5();
3736 case Mips::FeatureMips64r6:
3737 selectArch("mips64r6");
3738 getTargetStreamer().emitDirectiveSetMips64R6();
3744 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3745 MCAsmParser &Parser = getParser();
3746 if (getLexer().isNot(AsmToken::Comma)) {
3747 SMLoc Loc = getLexer().getLoc();
3748 Parser.eatToEndOfStatement();
3749 return Error(Loc, ErrorStr);
3752 Parser.Lex(); // Eat the comma.
3756 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3757 if (AssemblerOptions.back()->isReorder())
3758 Warning(Loc, ".cpload should be inside a noreorder section");
3760 if (inMips16Mode()) {
3761 reportParseError(".cpload is not supported in Mips16 mode");
3765 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3766 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3767 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3768 reportParseError("expected register containing function address");
3772 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3773 if (!RegOpnd.isGPRAsmReg()) {
3774 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3778 // If this is not the end of the statement, report an error.
3779 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3780 reportParseError("unexpected token, expected end of statement");
3784 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3788 bool MipsAsmParser::parseDirectiveCPSetup() {
3789 MCAsmParser &Parser = getParser();
3792 bool SaveIsReg = true;
3794 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3795 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3796 if (ResTy == MatchOperand_NoMatch) {
3797 reportParseError("expected register containing function address");
3798 Parser.eatToEndOfStatement();
3802 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3803 if (!FuncRegOpnd.isGPRAsmReg()) {
3804 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3805 Parser.eatToEndOfStatement();
3809 FuncReg = FuncRegOpnd.getGPR32Reg();
3812 if (!eatComma("unexpected token, expected comma"))
3815 ResTy = parseAnyRegister(TmpReg);
3816 if (ResTy == MatchOperand_NoMatch) {
3817 const AsmToken &Tok = Parser.getTok();
3818 if (Tok.is(AsmToken::Integer)) {
3819 Save = Tok.getIntVal();
3823 reportParseError("expected save register or stack offset");
3824 Parser.eatToEndOfStatement();
3828 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3829 if (!SaveOpnd.isGPRAsmReg()) {
3830 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3831 Parser.eatToEndOfStatement();
3834 Save = SaveOpnd.getGPR32Reg();
3837 if (!eatComma("unexpected token, expected comma"))
3841 if (Parser.parseExpression(Expr)) {
3842 reportParseError("expected expression");
3846 if (Expr->getKind() != MCExpr::SymbolRef) {
3847 reportParseError("expected symbol");
3850 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3852 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3857 bool MipsAsmParser::parseDirectiveNaN() {
3858 MCAsmParser &Parser = getParser();
3859 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3860 const AsmToken &Tok = Parser.getTok();
3862 if (Tok.getString() == "2008") {
3864 getTargetStreamer().emitDirectiveNaN2008();
3866 } else if (Tok.getString() == "legacy") {
3868 getTargetStreamer().emitDirectiveNaNLegacy();
3872 // If we don't recognize the option passed to the .nan
3873 // directive (e.g. no option or unknown option), emit an error.
3874 reportParseError("invalid option in .nan directive");
3878 bool MipsAsmParser::parseDirectiveSet() {
3879 MCAsmParser &Parser = getParser();
3880 // Get the next token.
3881 const AsmToken &Tok = Parser.getTok();
3883 if (Tok.getString() == "noat") {
3884 return parseSetNoAtDirective();
3885 } else if (Tok.getString() == "at") {
3886 return parseSetAtDirective();
3887 } else if (Tok.getString() == "arch") {
3888 return parseSetArchDirective();
3889 } else if (Tok.getString() == "fp") {
3890 return parseSetFpDirective();
3891 } else if (Tok.getString() == "pop") {
3892 return parseSetPopDirective();
3893 } else if (Tok.getString() == "push") {
3894 return parseSetPushDirective();
3895 } else if (Tok.getString() == "reorder") {
3896 return parseSetReorderDirective();
3897 } else if (Tok.getString() == "noreorder") {
3898 return parseSetNoReorderDirective();
3899 } else if (Tok.getString() == "macro") {
3900 return parseSetMacroDirective();
3901 } else if (Tok.getString() == "nomacro") {
3902 return parseSetNoMacroDirective();
3903 } else if (Tok.getString() == "mips16") {
3904 return parseSetMips16Directive();
3905 } else if (Tok.getString() == "nomips16") {
3906 return parseSetNoMips16Directive();
3907 } else if (Tok.getString() == "nomicromips") {
3908 getTargetStreamer().emitDirectiveSetNoMicroMips();
3909 Parser.eatToEndOfStatement();
3911 } else if (Tok.getString() == "micromips") {
3912 return parseSetFeature(Mips::FeatureMicroMips);
3913 } else if (Tok.getString() == "mips0") {
3914 return parseSetMips0Directive();
3915 } else if (Tok.getString() == "mips1") {
3916 return parseSetFeature(Mips::FeatureMips1);
3917 } else if (Tok.getString() == "mips2") {
3918 return parseSetFeature(Mips::FeatureMips2);
3919 } else if (Tok.getString() == "mips3") {
3920 return parseSetFeature(Mips::FeatureMips3);
3921 } else if (Tok.getString() == "mips4") {
3922 return parseSetFeature(Mips::FeatureMips4);
3923 } else if (Tok.getString() == "mips5") {
3924 return parseSetFeature(Mips::FeatureMips5);
3925 } else if (Tok.getString() == "mips32") {
3926 return parseSetFeature(Mips::FeatureMips32);
3927 } else if (Tok.getString() == "mips32r2") {
3928 return parseSetFeature(Mips::FeatureMips32r2);
3929 } else if (Tok.getString() == "mips32r3") {
3930 return parseSetFeature(Mips::FeatureMips32r3);
3931 } else if (Tok.getString() == "mips32r5") {
3932 return parseSetFeature(Mips::FeatureMips32r5);
3933 } else if (Tok.getString() == "mips32r6") {
3934 return parseSetFeature(Mips::FeatureMips32r6);
3935 } else if (Tok.getString() == "mips64") {
3936 return parseSetFeature(Mips::FeatureMips64);
3937 } else if (Tok.getString() == "mips64r2") {
3938 return parseSetFeature(Mips::FeatureMips64r2);
3939 } else if (Tok.getString() == "mips64r3") {
3940 return parseSetFeature(Mips::FeatureMips64r3);
3941 } else if (Tok.getString() == "mips64r5") {
3942 return parseSetFeature(Mips::FeatureMips64r5);
3943 } else if (Tok.getString() == "mips64r6") {
3944 return parseSetFeature(Mips::FeatureMips64r6);
3945 } else if (Tok.getString() == "dsp") {
3946 return parseSetFeature(Mips::FeatureDSP);
3947 } else if (Tok.getString() == "nodsp") {
3948 return parseSetNoDspDirective();
3949 } else if (Tok.getString() == "msa") {
3950 return parseSetMsaDirective();
3951 } else if (Tok.getString() == "nomsa") {
3952 return parseSetNoMsaDirective();
3954 // It is just an identifier, look for an assignment.
3955 parseSetAssignment();
3962 /// parseDataDirective
3963 /// ::= .word [ expression (, expression)* ]
3964 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3965 MCAsmParser &Parser = getParser();
3966 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3968 const MCExpr *Value;
3969 if (getParser().parseExpression(Value))
3972 getParser().getStreamer().EmitValue(Value, Size);
3974 if (getLexer().is(AsmToken::EndOfStatement))
3977 if (getLexer().isNot(AsmToken::Comma))
3978 return Error(L, "unexpected token, expected comma");
3987 /// parseDirectiveGpWord
3988 /// ::= .gpword local_sym
3989 bool MipsAsmParser::parseDirectiveGpWord() {
3990 MCAsmParser &Parser = getParser();
3991 const MCExpr *Value;
3992 // EmitGPRel32Value requires an expression, so we are using base class
3993 // method to evaluate the expression.
3994 if (getParser().parseExpression(Value))
3996 getParser().getStreamer().EmitGPRel32Value(Value);
3998 if (getLexer().isNot(AsmToken::EndOfStatement))
3999 return Error(getLexer().getLoc(),
4000 "unexpected token, expected end of statement");
4001 Parser.Lex(); // Eat EndOfStatement token.
4005 /// parseDirectiveGpDWord
4006 /// ::= .gpdword local_sym
4007 bool MipsAsmParser::parseDirectiveGpDWord() {
4008 MCAsmParser &Parser = getParser();
4009 const MCExpr *Value;
4010 // EmitGPRel64Value requires an expression, so we are using base class
4011 // method to evaluate the expression.
4012 if (getParser().parseExpression(Value))
4014 getParser().getStreamer().EmitGPRel64Value(Value);
4016 if (getLexer().isNot(AsmToken::EndOfStatement))
4017 return Error(getLexer().getLoc(),
4018 "unexpected token, expected end of statement");
4019 Parser.Lex(); // Eat EndOfStatement token.
4023 bool MipsAsmParser::parseDirectiveOption() {
4024 MCAsmParser &Parser = getParser();
4025 // Get the option token.
4026 AsmToken Tok = Parser.getTok();
4027 // At the moment only identifiers are supported.
4028 if (Tok.isNot(AsmToken::Identifier)) {
4029 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4030 Parser.eatToEndOfStatement();
4034 StringRef Option = Tok.getIdentifier();
4036 if (Option == "pic0") {
4037 getTargetStreamer().emitDirectiveOptionPic0();
4039 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4040 Error(Parser.getTok().getLoc(),
4041 "unexpected token, expected end of statement");
4042 Parser.eatToEndOfStatement();
4047 if (Option == "pic2") {
4048 getTargetStreamer().emitDirectiveOptionPic2();
4050 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4051 Error(Parser.getTok().getLoc(),
4052 "unexpected token, expected end of statement");
4053 Parser.eatToEndOfStatement();
4059 Warning(Parser.getTok().getLoc(),
4060 "unknown option, expected 'pic0' or 'pic2'");
4061 Parser.eatToEndOfStatement();
4065 /// parseInsnDirective
4067 bool MipsAsmParser::parseInsnDirective() {
4068 // If this is not the end of the statement, report an error.
4069 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4070 reportParseError("unexpected token, expected end of statement");
4074 // The actual label marking happens in
4075 // MipsELFStreamer::createPendingLabelRelocs().
4076 getTargetStreamer().emitDirectiveInsn();
4078 getParser().Lex(); // Eat EndOfStatement token.
4082 /// parseDirectiveModule
4083 /// ::= .module oddspreg
4084 /// ::= .module nooddspreg
4085 /// ::= .module fp=value
4086 bool MipsAsmParser::parseDirectiveModule() {
4087 MCAsmParser &Parser = getParser();
4088 MCAsmLexer &Lexer = getLexer();
4089 SMLoc L = Lexer.getLoc();
4091 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4092 // TODO : get a better message.
4093 reportParseError(".module directive must appear before any code");
4098 if (Parser.parseIdentifier(Option)) {
4099 reportParseError("expected .module option identifier");
4103 if (Option == "oddspreg") {
4104 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4105 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4107 // If this is not the end of the statement, report an error.
4108 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4109 reportParseError("unexpected token, expected end of statement");
4113 return false; // parseDirectiveModule has finished successfully.
4114 } else if (Option == "nooddspreg") {
4116 Error(L, "'.module nooddspreg' requires the O32 ABI");
4120 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4121 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4123 // If this is not the end of the statement, report an error.
4124 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4125 reportParseError("unexpected token, expected end of statement");
4129 return false; // parseDirectiveModule has finished successfully.
4130 } else if (Option == "fp") {
4131 return parseDirectiveModuleFP();
4133 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4137 /// parseDirectiveModuleFP
4141 bool MipsAsmParser::parseDirectiveModuleFP() {
4142 MCAsmParser &Parser = getParser();
4143 MCAsmLexer &Lexer = getLexer();
4145 if (Lexer.isNot(AsmToken::Equal)) {
4146 reportParseError("unexpected token, expected equals sign '='");
4149 Parser.Lex(); // Eat '=' token.
4151 MipsABIFlagsSection::FpABIKind FpABI;
4152 if (!parseFpABIValue(FpABI, ".module"))
4155 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4156 reportParseError("unexpected token, expected end of statement");
4160 // Emit appropriate flags.
4161 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4162 Parser.Lex(); // Consume the EndOfStatement.
4166 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4167 StringRef Directive) {
4168 MCAsmParser &Parser = getParser();
4169 MCAsmLexer &Lexer = getLexer();
4171 if (Lexer.is(AsmToken::Identifier)) {
4172 StringRef Value = Parser.getTok().getString();
4175 if (Value != "xx") {
4176 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4181 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4185 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4189 if (Lexer.is(AsmToken::Integer)) {
4190 unsigned Value = Parser.getTok().getIntVal();
4193 if (Value != 32 && Value != 64) {
4194 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4200 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4204 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4206 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4214 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4215 MCAsmParser &Parser = getParser();
4216 StringRef IDVal = DirectiveID.getString();
4218 if (IDVal == ".cpload")
4219 return parseDirectiveCpLoad(DirectiveID.getLoc());
4220 if (IDVal == ".dword") {
4221 parseDataDirective(8, DirectiveID.getLoc());
4224 if (IDVal == ".ent") {
4225 StringRef SymbolName;
4227 if (Parser.parseIdentifier(SymbolName)) {
4228 reportParseError("expected identifier after .ent");
4232 // There's an undocumented extension that allows an integer to
4233 // follow the name of the procedure which AFAICS is ignored by GAS.
4234 // Example: .ent foo,2
4235 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4236 if (getLexer().isNot(AsmToken::Comma)) {
4237 // Even though we accept this undocumented extension for compatibility
4238 // reasons, the additional integer argument does not actually change
4239 // the behaviour of the '.ent' directive, so we would like to discourage
4240 // its use. We do this by not referring to the extended version in
4241 // error messages which are not directly related to its use.
4242 reportParseError("unexpected token, expected end of statement");
4245 Parser.Lex(); // Eat the comma.
4246 const MCExpr *DummyNumber;
4247 int64_t DummyNumberVal;
4248 // If the user was explicitly trying to use the extended version,
4249 // we still give helpful extension-related error messages.
4250 if (Parser.parseExpression(DummyNumber)) {
4251 reportParseError("expected number after comma");
4254 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4255 reportParseError("expected an absolute expression after comma");
4260 // If this is not the end of the statement, report an error.
4261 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4262 reportParseError("unexpected token, expected end of statement");
4266 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4268 getTargetStreamer().emitDirectiveEnt(*Sym);
4273 if (IDVal == ".end") {
4274 StringRef SymbolName;
4276 if (Parser.parseIdentifier(SymbolName)) {
4277 reportParseError("expected identifier after .end");
4281 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4282 reportParseError("unexpected token, expected end of statement");
4286 if (CurrentFn == nullptr) {
4287 reportParseError(".end used without .ent");
4291 if ((SymbolName != CurrentFn->getName())) {
4292 reportParseError(".end symbol does not match .ent symbol");
4296 getTargetStreamer().emitDirectiveEnd(SymbolName);
4297 CurrentFn = nullptr;
4301 if (IDVal == ".frame") {
4302 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4303 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4304 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4305 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4306 reportParseError("expected stack register");
4310 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4311 if (!StackRegOpnd.isGPRAsmReg()) {
4312 reportParseError(StackRegOpnd.getStartLoc(),
4313 "expected general purpose register");
4316 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4318 if (Parser.getTok().is(AsmToken::Comma))
4321 reportParseError("unexpected token, expected comma");
4325 // Parse the frame size.
4326 const MCExpr *FrameSize;
4327 int64_t FrameSizeVal;
4329 if (Parser.parseExpression(FrameSize)) {
4330 reportParseError("expected frame size value");
4334 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4335 reportParseError("frame size not an absolute expression");
4339 if (Parser.getTok().is(AsmToken::Comma))
4342 reportParseError("unexpected token, expected comma");
4346 // Parse the return register.
4348 ResTy = parseAnyRegister(TmpReg);
4349 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4350 reportParseError("expected return register");
4354 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4355 if (!ReturnRegOpnd.isGPRAsmReg()) {
4356 reportParseError(ReturnRegOpnd.getStartLoc(),
4357 "expected general purpose register");
4361 // If this is not the end of the statement, report an error.
4362 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4363 reportParseError("unexpected token, expected end of statement");
4367 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4368 ReturnRegOpnd.getGPR32Reg());
4372 if (IDVal == ".set") {
4373 return parseDirectiveSet();
4376 if (IDVal == ".mask" || IDVal == ".fmask") {
4377 // .mask bitmask, frame_offset
4378 // bitmask: One bit for each register used.
4379 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4380 // first register is expected to be saved.
4382 // .mask 0x80000000, -4
4383 // .fmask 0x80000000, -4
4386 // Parse the bitmask
4387 const MCExpr *BitMask;
4390 if (Parser.parseExpression(BitMask)) {
4391 reportParseError("expected bitmask value");
4395 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4396 reportParseError("bitmask not an absolute expression");
4400 if (Parser.getTok().is(AsmToken::Comma))
4403 reportParseError("unexpected token, expected comma");
4407 // Parse the frame_offset
4408 const MCExpr *FrameOffset;
4409 int64_t FrameOffsetVal;
4411 if (Parser.parseExpression(FrameOffset)) {
4412 reportParseError("expected frame offset value");
4416 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4417 reportParseError("frame offset not an absolute expression");
4421 // If this is not the end of the statement, report an error.
4422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4423 reportParseError("unexpected token, expected end of statement");
4427 if (IDVal == ".mask")
4428 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4430 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4434 if (IDVal == ".nan")
4435 return parseDirectiveNaN();
4437 if (IDVal == ".gpword") {
4438 parseDirectiveGpWord();
4442 if (IDVal == ".gpdword") {
4443 parseDirectiveGpDWord();
4447 if (IDVal == ".word") {
4448 parseDataDirective(4, DirectiveID.getLoc());
4452 if (IDVal == ".option")
4453 return parseDirectiveOption();
4455 if (IDVal == ".abicalls") {
4456 getTargetStreamer().emitDirectiveAbiCalls();
4457 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4458 Error(Parser.getTok().getLoc(),
4459 "unexpected token, expected end of statement");
4461 Parser.eatToEndOfStatement();
4466 if (IDVal == ".cpsetup")
4467 return parseDirectiveCPSetup();
4469 if (IDVal == ".module")
4470 return parseDirectiveModule();
4472 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4473 return parseInternalDirectiveReallowModule();
4475 if (IDVal == ".insn")
4476 return parseInsnDirective();
4481 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4482 // If this is not the end of the statement, report an error.
4483 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4484 reportParseError("unexpected token, expected end of statement");
4488 getTargetStreamer().reallowModuleDirective();
4490 getParser().Lex(); // Eat EndOfStatement token.
4494 extern "C" void LLVMInitializeMipsAsmParser() {
4495 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4496 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4497 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4498 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4501 #define GET_REGISTER_MATCHER
4502 #define GET_MATCHER_IMPLEMENTATION
4503 #include "MipsGenAsmMatcher.inc"