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 expandLoadImm(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
190 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
200 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
203 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 bool reportParseError(Twine ErrorMsg);
207 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
209 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
210 bool parseRelocOperand(const MCExpr *&Res);
212 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
214 bool isEvaluated(const MCExpr *Expr);
215 bool parseSetMips0Directive();
216 bool parseSetArchDirective();
217 bool parseSetFeature(uint64_t Feature);
218 bool parseDirectiveCpLoad(SMLoc Loc);
219 bool parseDirectiveCPSetup();
220 bool parseDirectiveNaN();
221 bool parseDirectiveSet();
222 bool parseDirectiveOption();
223 bool parseInsnDirective();
225 bool parseSetAtDirective();
226 bool parseSetNoAtDirective();
227 bool parseSetMacroDirective();
228 bool parseSetNoMacroDirective();
229 bool parseSetMsaDirective();
230 bool parseSetNoMsaDirective();
231 bool parseSetNoDspDirective();
232 bool parseSetReorderDirective();
233 bool parseSetNoReorderDirective();
234 bool parseSetMips16Directive();
235 bool parseSetNoMips16Directive();
236 bool parseSetFpDirective();
237 bool parseSetPopDirective();
238 bool parseSetPushDirective();
240 bool parseSetAssignment();
242 bool parseDataDirective(unsigned Size, SMLoc L);
243 bool parseDirectiveGpWord();
244 bool parseDirectiveGpDWord();
245 bool parseDirectiveModule();
246 bool parseDirectiveModuleFP();
247 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
248 StringRef Directive);
250 bool parseInternalDirectiveReallowModule();
252 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
254 bool eatComma(StringRef ErrorStr);
256 int matchCPURegisterName(StringRef Symbol);
258 int matchHWRegsRegisterName(StringRef Symbol);
260 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
262 int matchFPURegisterName(StringRef Name);
264 int matchFCCRegisterName(StringRef Name);
266 int matchACRegisterName(StringRef Name);
268 int matchMSA128RegisterName(StringRef Name);
270 int matchMSA128CtrlRegisterName(StringRef Name);
272 unsigned getReg(int RC, int RegNo);
274 unsigned getGPR(int RegNo);
276 /// Returns the internal register number for the current AT. Also checks if
277 /// the current AT is unavailable (set to $0) and gives an error if it is.
278 /// This should be used in pseudo-instruction expansions which need AT.
279 unsigned getATReg(SMLoc Loc);
281 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
282 SmallVectorImpl<MCInst> &Instructions);
284 // Helper function that checks if the value of a vector index is within the
285 // boundaries of accepted values for each RegisterKind
286 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
287 bool validateMSAIndex(int Val, int RegKind);
289 // Selects a new architecture by updating the FeatureBits with the necessary
290 // info including implied dependencies.
291 // Internally, it clears all the feature bits related to *any* architecture
292 // and selects the new one using the ToggleFeature functionality of the
293 // MCSubtargetInfo object that handles implied dependencies. The reason we
294 // clear all the arch related bits manually is because ToggleFeature only
295 // clears the features that imply the feature being cleared and not the
296 // features implied by the feature being cleared. This is easier to see
298 // --------------------------------------------------
299 // | Feature | Implies |
300 // | -------------------------------------------------|
301 // | FeatureMips1 | None |
302 // | FeatureMips2 | FeatureMips1 |
303 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
304 // | FeatureMips4 | FeatureMips3 |
306 // --------------------------------------------------
308 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
309 // FeatureMipsGP64 | FeatureMips1)
310 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
311 void selectArch(StringRef ArchFeature) {
312 uint64_t FeatureBits = STI.getFeatureBits();
313 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
314 STI.setFeatureBits(FeatureBits);
315 setAvailableFeatures(
316 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
317 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
320 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
321 if (!(STI.getFeatureBits() & Feature)) {
322 setAvailableFeatures(
323 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
325 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
328 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
329 if (STI.getFeatureBits() & Feature) {
330 setAvailableFeatures(
331 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
333 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
337 enum MipsMatchResultTy {
338 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
339 #define GET_OPERAND_DIAGNOSTIC_TYPES
340 #include "MipsGenAsmMatcher.inc"
341 #undef GET_OPERAND_DIAGNOSTIC_TYPES
345 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
346 const MCInstrInfo &MII, const MCTargetOptions &Options)
347 : MCTargetAsmParser(), STI(sti),
348 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
349 sti.getCPU(), Options)) {
350 MCAsmParserExtension::Initialize(parser);
352 parser.addAliasForDirective(".asciiz", ".asciz");
354 // Initialize the set of available features.
355 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
357 // Remember the initial assembler options. The user can not modify these.
358 AssemblerOptions.push_back(
359 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
361 // Create an assembler options environment for the user to modify.
362 AssemblerOptions.push_back(
363 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
365 getTargetStreamer().updateABIInfo(*this);
367 if (!isABI_O32() && !useOddSPReg() != 0)
368 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
373 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
374 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
376 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
377 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
378 const MipsABIInfo &getABI() const { return ABI; }
379 bool isABI_N32() const { return ABI.IsN32(); }
380 bool isABI_N64() const { return ABI.IsN64(); }
381 bool isABI_O32() const { return ABI.IsO32(); }
382 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
384 bool useOddSPReg() const {
385 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
388 bool inMicroMipsMode() const {
389 return STI.getFeatureBits() & Mips::FeatureMicroMips;
391 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
392 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
393 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
394 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
395 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
396 bool hasMips32() const {
397 return (STI.getFeatureBits() & Mips::FeatureMips32);
399 bool hasMips64() const {
400 return (STI.getFeatureBits() & Mips::FeatureMips64);
402 bool hasMips32r2() const {
403 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
405 bool hasMips64r2() const {
406 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
408 bool hasMips32r3() const {
409 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
411 bool hasMips64r3() const {
412 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
414 bool hasMips32r5() const {
415 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
417 bool hasMips64r5() const {
418 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
420 bool hasMips32r6() const {
421 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
423 bool hasMips64r6() const {
424 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
426 bool hasCnMips() const {
427 return (STI.getFeatureBits() & Mips::FeatureCnMips);
429 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
430 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
431 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
433 bool inMips16Mode() const {
434 return STI.getFeatureBits() & Mips::FeatureMips16;
436 // TODO: see how can we get this info.
437 bool abiUsesSoftFloat() const { return false; }
439 /// Warn if RegIndex is the same as the current AT.
440 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
446 /// MipsOperand - Instances of this class represent a parsed Mips machine
448 class MipsOperand : public MCParsedAsmOperand {
450 /// Broad categories of register classes
451 /// The exact class is finalized by the render method.
453 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
454 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
456 RegKind_FCC = 4, /// FCC
457 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
458 RegKind_MSACtrl = 16, /// MSA control registers
459 RegKind_COP2 = 32, /// COP2
460 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
462 RegKind_CCR = 128, /// CCR
463 RegKind_HWRegs = 256, /// HWRegs
464 RegKind_COP3 = 512, /// COP3
466 /// Potentially any (e.g. $1)
467 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
468 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
469 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
474 k_Immediate, /// An immediate (possibly involving symbol references)
475 k_Memory, /// Base + Offset Memory Address
476 k_PhysRegister, /// A physical register from the Mips namespace
477 k_RegisterIndex, /// A register index in one or more RegKind.
478 k_Token, /// A simple token
479 k_RegList, /// A physical register list
480 k_RegPair /// A pair of physical register
484 MipsOperand(KindTy K, MipsAsmParser &Parser)
485 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
488 /// For diagnostics, and checking the assembler temporary
489 MipsAsmParser &AsmParser;
497 unsigned Num; /// Register Number
501 unsigned Index; /// Index into the register class
502 RegKind Kind; /// Bitfield of the kinds it could possibly be
503 const MCRegisterInfo *RegInfo;
516 SmallVector<unsigned, 10> *List;
521 struct PhysRegOp PhysReg;
522 struct RegIdxOp RegIdx;
525 struct RegListOp RegList;
528 SMLoc StartLoc, EndLoc;
530 /// Internal constructor for register kinds
531 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
532 const MCRegisterInfo *RegInfo,
534 MipsAsmParser &Parser) {
535 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
536 Op->RegIdx.Index = Index;
537 Op->RegIdx.RegInfo = RegInfo;
538 Op->RegIdx.Kind = RegKind;
545 /// Coerce the register to GPR32 and return the real register for the current
547 unsigned getGPR32Reg() const {
548 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
549 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
550 unsigned ClassID = Mips::GPR32RegClassID;
551 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
554 /// Coerce the register to GPR32 and return the real register for the current
556 unsigned getGPRMM16Reg() const {
557 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
558 unsigned ClassID = Mips::GPR32RegClassID;
559 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
562 /// Coerce the register to GPR64 and return the real register for the current
564 unsigned getGPR64Reg() const {
565 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
566 unsigned ClassID = Mips::GPR64RegClassID;
567 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
571 /// Coerce the register to AFGR64 and return the real register for the current
573 unsigned getAFGR64Reg() const {
574 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
575 if (RegIdx.Index % 2 != 0)
576 AsmParser.Warning(StartLoc, "Float register should be even.");
577 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
578 .getRegister(RegIdx.Index / 2);
581 /// Coerce the register to FGR64 and return the real register for the current
583 unsigned getFGR64Reg() const {
584 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
585 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
586 .getRegister(RegIdx.Index);
589 /// Coerce the register to FGR32 and return the real register for the current
591 unsigned getFGR32Reg() const {
592 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
593 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
594 .getRegister(RegIdx.Index);
597 /// Coerce the register to FGRH32 and return the real register for the current
599 unsigned getFGRH32Reg() const {
600 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
601 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
602 .getRegister(RegIdx.Index);
605 /// Coerce the register to FCC and return the real register for the current
607 unsigned getFCCReg() const {
608 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
609 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
610 .getRegister(RegIdx.Index);
613 /// Coerce the register to MSA128 and return the real register for the current
615 unsigned getMSA128Reg() const {
616 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
617 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
619 unsigned ClassID = Mips::MSA128BRegClassID;
620 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
623 /// Coerce the register to MSACtrl and return the real register for the
625 unsigned getMSACtrlReg() const {
626 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
627 unsigned ClassID = Mips::MSACtrlRegClassID;
628 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
631 /// Coerce the register to COP2 and return the real register for the
633 unsigned getCOP2Reg() const {
634 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
635 unsigned ClassID = Mips::COP2RegClassID;
636 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
639 /// Coerce the register to COP3 and return the real register for the
641 unsigned getCOP3Reg() const {
642 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
643 unsigned ClassID = Mips::COP3RegClassID;
644 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
647 /// Coerce the register to ACC64DSP and return the real register for the
649 unsigned getACC64DSPReg() const {
650 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
651 unsigned ClassID = Mips::ACC64DSPRegClassID;
652 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
655 /// Coerce the register to HI32DSP and return the real register for the
657 unsigned getHI32DSPReg() const {
658 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
659 unsigned ClassID = Mips::HI32DSPRegClassID;
660 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
663 /// Coerce the register to LO32DSP and return the real register for the
665 unsigned getLO32DSPReg() const {
666 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
667 unsigned ClassID = Mips::LO32DSPRegClassID;
668 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
671 /// Coerce the register to CCR and return the real register for the
673 unsigned getCCRReg() const {
674 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
675 unsigned ClassID = Mips::CCRRegClassID;
676 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
679 /// Coerce the register to HWRegs and return the real register for the
681 unsigned getHWRegsReg() const {
682 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
683 unsigned ClassID = Mips::HWRegsRegClassID;
684 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
688 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
689 // Add as immediate when possible. Null MCExpr = 0.
691 Inst.addOperand(MCOperand::CreateImm(0));
692 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
693 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
695 Inst.addOperand(MCOperand::CreateExpr(Expr));
698 void addRegOperands(MCInst &Inst, unsigned N) const {
699 llvm_unreachable("Use a custom parser instead");
702 /// Render the operand to an MCInst as a GPR32
703 /// Asserts if the wrong number of operands are requested, or the operand
704 /// is not a k_RegisterIndex compatible with RegKind_GPR
705 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
706 assert(N == 1 && "Invalid number of operands!");
707 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
710 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
711 assert(N == 1 && "Invalid number of operands!");
712 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
715 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
716 assert(N == 1 && "Invalid number of operands!");
717 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
720 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
721 assert(N == 1 && "Invalid number of operands!");
722 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
725 /// Render the operand to an MCInst as a GPR64
726 /// Asserts if the wrong number of operands are requested, or the operand
727 /// is not a k_RegisterIndex compatible with RegKind_GPR
728 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
729 assert(N == 1 && "Invalid number of operands!");
730 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
733 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
734 assert(N == 1 && "Invalid number of operands!");
735 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
738 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
739 assert(N == 1 && "Invalid number of operands!");
740 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
743 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
744 assert(N == 1 && "Invalid number of operands!");
745 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
746 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
747 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
748 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
752 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
753 assert(N == 1 && "Invalid number of operands!");
754 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
757 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
758 assert(N == 1 && "Invalid number of operands!");
759 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
762 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
763 assert(N == 1 && "Invalid number of operands!");
764 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
767 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
768 assert(N == 1 && "Invalid number of operands!");
769 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
772 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
773 assert(N == 1 && "Invalid number of operands!");
774 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
777 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
778 assert(N == 1 && "Invalid number of operands!");
779 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
782 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
783 assert(N == 1 && "Invalid number of operands!");
784 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
787 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
788 assert(N == 1 && "Invalid number of operands!");
789 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
792 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
793 assert(N == 1 && "Invalid number of operands!");
794 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
797 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
798 assert(N == 1 && "Invalid number of operands!");
799 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
802 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
803 assert(N == 1 && "Invalid number of operands!");
804 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
807 void addImmOperands(MCInst &Inst, unsigned N) const {
808 assert(N == 1 && "Invalid number of operands!");
809 const MCExpr *Expr = getImm();
813 void addMemOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 2 && "Invalid number of operands!");
816 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
818 const MCExpr *Expr = getMemOff();
822 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 2 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
827 const MCExpr *Expr = getMemOff();
831 void addRegListOperands(MCInst &Inst, unsigned N) const {
832 assert(N == 1 && "Invalid number of operands!");
834 for (auto RegNo : getRegList())
835 Inst.addOperand(MCOperand::CreateReg(RegNo));
838 void addRegPairOperands(MCInst &Inst, unsigned N) const {
839 assert(N == 2 && "Invalid number of operands!");
840 unsigned RegNo = getRegPair();
841 Inst.addOperand(MCOperand::CreateReg(RegNo++));
842 Inst.addOperand(MCOperand::CreateReg(RegNo));
845 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
846 assert(N == 2 && "Invalid number of operands!");
847 for (auto RegNo : getRegList())
848 Inst.addOperand(MCOperand::CreateReg(RegNo));
851 bool isReg() const override {
852 // As a special case until we sort out the definition of div/divu, pretend
853 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
854 if (isGPRAsmReg() && RegIdx.Index == 0)
857 return Kind == k_PhysRegister;
859 bool isRegIdx() const { return Kind == k_RegisterIndex; }
860 bool isImm() const override { return Kind == k_Immediate; }
861 bool isConstantImm() const {
862 return isImm() && dyn_cast<MCConstantExpr>(getImm());
864 bool isToken() const override {
865 // Note: It's not possible to pretend that other operand kinds are tokens.
866 // The matcher emitter checks tokens first.
867 return Kind == k_Token;
869 bool isMem() const override { return Kind == k_Memory; }
870 bool isConstantMemOff() const {
871 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
873 template <unsigned Bits> bool isMemWithSimmOffset() const {
874 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
876 bool isMemWithGRPMM16Base() const {
877 return isMem() && getMemBase()->isMM16AsmReg();
879 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
880 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
881 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
883 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
884 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
885 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
886 && (getMemBase()->getGPR32Reg() == Mips::SP);
888 bool isRegList16() const {
892 int Size = RegList.List->size();
893 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
894 RegList.List->back() != Mips::RA)
897 int PrevReg = *RegList.List->begin();
898 for (int i = 1; i < Size - 1; i++) {
899 int Reg = (*(RegList.List))[i];
900 if ( Reg != PrevReg + 1)
907 bool isInvNum() const { return Kind == k_Immediate; }
908 bool isLSAImm() const {
909 if (!isConstantImm())
911 int64_t Val = getConstantImm();
912 return 1 <= Val && Val <= 4;
914 bool isRegList() const { return Kind == k_RegList; }
915 bool isMovePRegPair() const {
916 if (Kind != k_RegList || RegList.List->size() != 2)
919 unsigned R0 = RegList.List->front();
920 unsigned R1 = RegList.List->back();
922 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
923 (R0 == Mips::A1 && R1 == Mips::A3) ||
924 (R0 == Mips::A2 && R1 == Mips::A3) ||
925 (R0 == Mips::A0 && R1 == Mips::S5) ||
926 (R0 == Mips::A0 && R1 == Mips::S6) ||
927 (R0 == Mips::A0 && R1 == Mips::A1) ||
928 (R0 == Mips::A0 && R1 == Mips::A2) ||
929 (R0 == Mips::A0 && R1 == Mips::A3))
935 StringRef getToken() const {
936 assert(Kind == k_Token && "Invalid access!");
937 return StringRef(Tok.Data, Tok.Length);
939 bool isRegPair() const { return Kind == k_RegPair; }
941 unsigned getReg() const override {
942 // As a special case until we sort out the definition of div/divu, pretend
943 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
944 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
945 RegIdx.Kind & RegKind_GPR)
946 return getGPR32Reg(); // FIXME: GPR64 too
948 assert(Kind == k_PhysRegister && "Invalid access!");
952 const MCExpr *getImm() const {
953 assert((Kind == k_Immediate) && "Invalid access!");
957 int64_t getConstantImm() const {
958 const MCExpr *Val = getImm();
959 return static_cast<const MCConstantExpr *>(Val)->getValue();
962 MipsOperand *getMemBase() const {
963 assert((Kind == k_Memory) && "Invalid access!");
967 const MCExpr *getMemOff() const {
968 assert((Kind == k_Memory) && "Invalid access!");
972 int64_t getConstantMemOff() const {
973 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
976 const SmallVectorImpl<unsigned> &getRegList() const {
977 assert((Kind == k_RegList) && "Invalid access!");
978 return *(RegList.List);
981 unsigned getRegPair() const {
982 assert((Kind == k_RegPair) && "Invalid access!");
986 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
987 MipsAsmParser &Parser) {
988 auto Op = make_unique<MipsOperand>(k_Token, Parser);
989 Op->Tok.Data = Str.data();
990 Op->Tok.Length = Str.size();
996 /// Create a numeric register (e.g. $1). The exact register remains
997 /// unresolved until an instruction successfully matches
998 static std::unique_ptr<MipsOperand>
999 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1000 SMLoc E, MipsAsmParser &Parser) {
1001 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1002 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1005 /// Create a register that is definitely a GPR.
1006 /// This is typically only used for named registers such as $gp.
1007 static std::unique_ptr<MipsOperand>
1008 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1009 MipsAsmParser &Parser) {
1010 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1013 /// Create a register that is definitely a FGR.
1014 /// This is typically only used for named registers such as $f0.
1015 static std::unique_ptr<MipsOperand>
1016 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1017 MipsAsmParser &Parser) {
1018 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1021 /// Create a register that is definitely a HWReg.
1022 /// This is typically only used for named registers such as $hwr_cpunum.
1023 static std::unique_ptr<MipsOperand>
1024 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1025 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1026 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1029 /// Create a register that is definitely an FCC.
1030 /// This is typically only used for named registers such as $fcc0.
1031 static std::unique_ptr<MipsOperand>
1032 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1033 MipsAsmParser &Parser) {
1034 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1037 /// Create a register that is definitely an ACC.
1038 /// This is typically only used for named registers such as $ac0.
1039 static std::unique_ptr<MipsOperand>
1040 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1041 MipsAsmParser &Parser) {
1042 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1045 /// Create a register that is definitely an MSA128.
1046 /// This is typically only used for named registers such as $w0.
1047 static std::unique_ptr<MipsOperand>
1048 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1049 SMLoc E, MipsAsmParser &Parser) {
1050 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1053 /// Create a register that is definitely an MSACtrl.
1054 /// This is typically only used for named registers such as $msaaccess.
1055 static std::unique_ptr<MipsOperand>
1056 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1057 SMLoc E, MipsAsmParser &Parser) {
1058 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1061 static std::unique_ptr<MipsOperand>
1062 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1063 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1070 static std::unique_ptr<MipsOperand>
1071 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1072 SMLoc E, MipsAsmParser &Parser) {
1073 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1074 Op->Mem.Base = Base.release();
1081 static std::unique_ptr<MipsOperand>
1082 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1083 MipsAsmParser &Parser) {
1084 assert (Regs.size() > 0 && "Empty list not allowed");
1086 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1087 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1088 Op->StartLoc = StartLoc;
1089 Op->EndLoc = EndLoc;
1093 static std::unique_ptr<MipsOperand>
1094 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1095 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1096 Op->RegIdx.Index = RegNo;
1102 bool isGPRAsmReg() const {
1103 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1105 bool isMM16AsmReg() const {
1106 if (!(isRegIdx() && RegIdx.Kind))
1108 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1109 || RegIdx.Index == 16 || RegIdx.Index == 17);
1111 bool isMM16AsmRegZero() const {
1112 if (!(isRegIdx() && RegIdx.Kind))
1114 return (RegIdx.Index == 0 ||
1115 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1116 RegIdx.Index == 17);
1118 bool isMM16AsmRegMoveP() const {
1119 if (!(isRegIdx() && RegIdx.Kind))
1121 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1122 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1124 bool isFGRAsmReg() const {
1125 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1126 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1128 bool isHWRegsAsmReg() const {
1129 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1131 bool isCCRAsmReg() const {
1132 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1134 bool isFCCAsmReg() const {
1135 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1137 if (!AsmParser.hasEightFccRegisters())
1138 return RegIdx.Index == 0;
1139 return RegIdx.Index <= 7;
1141 bool isACCAsmReg() const {
1142 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1144 bool isCOP2AsmReg() const {
1145 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1147 bool isCOP3AsmReg() const {
1148 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1150 bool isMSA128AsmReg() const {
1151 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1153 bool isMSACtrlAsmReg() const {
1154 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1157 /// getStartLoc - Get the location of the first token of this operand.
1158 SMLoc getStartLoc() const override { return StartLoc; }
1159 /// getEndLoc - Get the location of the last token of this operand.
1160 SMLoc getEndLoc() const override { return EndLoc; }
1162 virtual ~MipsOperand() {
1170 delete RegList.List;
1171 case k_PhysRegister:
1172 case k_RegisterIndex:
1179 void print(raw_ostream &OS) const override {
1188 Mem.Base->print(OS);
1193 case k_PhysRegister:
1194 OS << "PhysReg<" << PhysReg.Num << ">";
1196 case k_RegisterIndex:
1197 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1204 for (auto Reg : (*RegList.List))
1209 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1213 }; // class MipsOperand
1217 extern const MCInstrDesc MipsInsts[];
1219 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1220 return MipsInsts[Opcode];
1223 static bool hasShortDelaySlot(unsigned Opcode) {
1226 case Mips::JALRS_MM:
1227 case Mips::JALRS16_MM:
1228 case Mips::BGEZALS_MM:
1229 case Mips::BLTZALS_MM:
1236 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1237 SmallVectorImpl<MCInst> &Instructions) {
1238 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1242 if (MCID.isBranch() || MCID.isCall()) {
1243 const unsigned Opcode = Inst.getOpcode();
1253 assert(hasCnMips() && "instruction only valid for octeon cpus");
1260 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1261 Offset = Inst.getOperand(2);
1262 if (!Offset.isImm())
1263 break; // We'll deal with this situation later on when applying fixups.
1264 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1265 return Error(IDLoc, "branch target out of range");
1266 if (OffsetToAlignment(Offset.getImm(),
1267 1LL << (inMicroMipsMode() ? 1 : 2)))
1268 return Error(IDLoc, "branch to misaligned address");
1282 case Mips::BGEZAL_MM:
1283 case Mips::BLTZAL_MM:
1286 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1287 Offset = Inst.getOperand(1);
1288 if (!Offset.isImm())
1289 break; // We'll deal with this situation later on when applying fixups.
1290 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1291 return Error(IDLoc, "branch target out of range");
1292 if (OffsetToAlignment(Offset.getImm(),
1293 1LL << (inMicroMipsMode() ? 1 : 2)))
1294 return Error(IDLoc, "branch to misaligned address");
1296 case Mips::BEQZ16_MM:
1297 case Mips::BNEZ16_MM:
1298 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1299 Offset = Inst.getOperand(1);
1300 if (!Offset.isImm())
1301 break; // We'll deal with this situation later on when applying fixups.
1302 if (!isIntN(8, Offset.getImm()))
1303 return Error(IDLoc, "branch target out of range");
1304 if (OffsetToAlignment(Offset.getImm(), 2LL))
1305 return Error(IDLoc, "branch to misaligned address");
1310 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1311 // We still accept it but it is a normal nop.
1312 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1313 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1314 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1319 const unsigned Opcode = Inst.getOpcode();
1331 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1332 // The offset is handled above
1333 Opnd = Inst.getOperand(1);
1335 return Error(IDLoc, "expected immediate operand kind");
1336 Imm = Opnd.getImm();
1337 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1338 Opcode == Mips::BBIT1 ? 63 : 31))
1339 return Error(IDLoc, "immediate operand value out of range");
1341 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1343 Inst.getOperand(1).setImm(Imm - 32);
1351 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1353 Opnd = Inst.getOperand(3);
1355 return Error(IDLoc, "expected immediate operand kind");
1356 Imm = Opnd.getImm();
1357 if (Imm < 0 || Imm > 31)
1358 return Error(IDLoc, "immediate operand value out of range");
1360 Opnd = Inst.getOperand(2);
1362 return Error(IDLoc, "expected immediate operand kind");
1363 Imm = Opnd.getImm();
1364 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1365 Opcode == Mips::EXTS ? 63 : 31))
1366 return Error(IDLoc, "immediate operand value out of range");
1368 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1369 Inst.getOperand(2).setImm(Imm - 32);
1375 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1376 Opnd = Inst.getOperand(2);
1378 return Error(IDLoc, "expected immediate operand kind");
1379 Imm = Opnd.getImm();
1380 if (!isInt<10>(Imm))
1381 return Error(IDLoc, "immediate operand value out of range");
1386 if (MCID.mayLoad() || MCID.mayStore()) {
1387 // Check the offset of memory operand, if it is a symbol
1388 // reference or immediate we may have to expand instructions.
1389 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1390 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1391 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1392 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1393 MCOperand &Op = Inst.getOperand(i);
1395 int MemOffset = Op.getImm();
1396 if (MemOffset < -32768 || MemOffset > 32767) {
1397 // Offset can't exceed 16bit value.
1398 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1401 } else if (Op.isExpr()) {
1402 const MCExpr *Expr = Op.getExpr();
1403 if (Expr->getKind() == MCExpr::SymbolRef) {
1404 const MCSymbolRefExpr *SR =
1405 static_cast<const MCSymbolRefExpr *>(Expr);
1406 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1408 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1411 } else if (!isEvaluated(Expr)) {
1412 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1420 if (inMicroMipsMode()) {
1421 if (MCID.mayLoad()) {
1422 // Try to create 16-bit GP relative load instruction.
1423 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1424 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1425 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1426 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1427 MCOperand &Op = Inst.getOperand(i);
1429 int MemOffset = Op.getImm();
1430 MCOperand &DstReg = Inst.getOperand(0);
1431 MCOperand &BaseReg = Inst.getOperand(1);
1432 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1433 getContext().getRegisterInfo()->getRegClass(
1434 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1435 BaseReg.getReg() == Mips::GP) {
1437 TmpInst.setLoc(IDLoc);
1438 TmpInst.setOpcode(Mips::LWGP_MM);
1439 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1440 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1441 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1442 Instructions.push_back(TmpInst);
1450 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1455 switch (Inst.getOpcode()) {
1458 case Mips::ADDIUS5_MM:
1459 Opnd = Inst.getOperand(2);
1461 return Error(IDLoc, "expected immediate operand kind");
1462 Imm = Opnd.getImm();
1463 if (Imm < -8 || Imm > 7)
1464 return Error(IDLoc, "immediate operand value out of range");
1466 case Mips::ADDIUSP_MM:
1467 Opnd = Inst.getOperand(0);
1469 return Error(IDLoc, "expected immediate operand kind");
1470 Imm = Opnd.getImm();
1471 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1473 return Error(IDLoc, "immediate operand value out of range");
1475 case Mips::SLL16_MM:
1476 case Mips::SRL16_MM:
1477 Opnd = Inst.getOperand(2);
1479 return Error(IDLoc, "expected immediate operand kind");
1480 Imm = Opnd.getImm();
1481 if (Imm < 1 || Imm > 8)
1482 return Error(IDLoc, "immediate operand value out of range");
1485 Opnd = Inst.getOperand(1);
1487 return Error(IDLoc, "expected immediate operand kind");
1488 Imm = Opnd.getImm();
1489 if (Imm < -1 || Imm > 126)
1490 return Error(IDLoc, "immediate operand value out of range");
1492 case Mips::ADDIUR2_MM:
1493 Opnd = Inst.getOperand(2);
1495 return Error(IDLoc, "expected immediate operand kind");
1496 Imm = Opnd.getImm();
1497 if (!(Imm == 1 || Imm == -1 ||
1498 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1499 return Error(IDLoc, "immediate operand value out of range");
1501 case Mips::ADDIUR1SP_MM:
1502 Opnd = Inst.getOperand(1);
1504 return Error(IDLoc, "expected immediate operand kind");
1505 Imm = Opnd.getImm();
1506 if (OffsetToAlignment(Imm, 4LL))
1507 return Error(IDLoc, "misaligned immediate operand value");
1508 if (Imm < 0 || Imm > 255)
1509 return Error(IDLoc, "immediate operand value out of range");
1511 case Mips::ANDI16_MM:
1512 Opnd = Inst.getOperand(2);
1514 return Error(IDLoc, "expected immediate operand kind");
1515 Imm = Opnd.getImm();
1516 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1517 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1518 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1519 return Error(IDLoc, "immediate operand value out of range");
1521 case Mips::LBU16_MM:
1522 Opnd = Inst.getOperand(2);
1524 return Error(IDLoc, "expected immediate operand kind");
1525 Imm = Opnd.getImm();
1526 if (Imm < -1 || Imm > 14)
1527 return Error(IDLoc, "immediate operand value out of range");
1530 Opnd = Inst.getOperand(2);
1532 return Error(IDLoc, "expected immediate operand kind");
1533 Imm = Opnd.getImm();
1534 if (Imm < 0 || Imm > 15)
1535 return Error(IDLoc, "immediate operand value out of range");
1537 case Mips::LHU16_MM:
1539 Opnd = Inst.getOperand(2);
1541 return Error(IDLoc, "expected immediate operand kind");
1542 Imm = Opnd.getImm();
1543 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1544 return Error(IDLoc, "immediate operand value out of range");
1548 Opnd = Inst.getOperand(2);
1550 return Error(IDLoc, "expected immediate operand kind");
1551 Imm = Opnd.getImm();
1552 if (Imm < 0 || Imm > 60 || (Imm % 4 != 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 (!isUInt<5>(Imm))
1562 return Error(IDLoc, "immediate operand value out of range");
1564 case Mips::ADDIUPC_MM:
1565 MCOperand Opnd = Inst.getOperand(1);
1567 return Error(IDLoc, "expected immediate operand kind");
1568 int Imm = Opnd.getImm();
1569 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1570 return Error(IDLoc, "immediate operand value out of range");
1575 if (needsExpansion(Inst)) {
1576 if (expandInstruction(Inst, IDLoc, Instructions))
1579 Instructions.push_back(Inst);
1581 // If this instruction has a delay slot and .set reorder is active,
1582 // emit a NOP after it.
1583 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1584 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1589 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1591 switch (Inst.getOpcode()) {
1592 case Mips::LoadImm32:
1593 case Mips::LoadImm64:
1594 case Mips::LoadAddrImm32:
1595 case Mips::LoadAddrReg32:
1596 case Mips::B_MM_Pseudo:
1599 case Mips::JalOneReg:
1600 case Mips::JalTwoReg:
1607 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1608 SmallVectorImpl<MCInst> &Instructions) {
1609 switch (Inst.getOpcode()) {
1610 default: llvm_unreachable("unimplemented expansion");
1611 case Mips::LoadImm32:
1612 return expandLoadImm(Inst, IDLoc, Instructions);
1613 case Mips::LoadImm64:
1615 Error(IDLoc, "instruction requires a 64-bit architecture");
1618 return expandLoadImm(Inst, IDLoc, Instructions);
1619 case Mips::LoadAddrImm32:
1620 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1621 case Mips::LoadAddrReg32:
1622 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1623 case Mips::B_MM_Pseudo:
1624 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1627 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1628 case Mips::JalOneReg:
1629 case Mips::JalTwoReg:
1630 return expandJalWithRegs(Inst, IDLoc, Instructions);
1635 template <bool PerformShift>
1636 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1637 SmallVectorImpl<MCInst> &Instructions) {
1640 tmpInst.setOpcode(Mips::DSLL);
1641 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1642 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1643 tmpInst.addOperand(MCOperand::CreateImm(16));
1644 tmpInst.setLoc(IDLoc);
1645 Instructions.push_back(tmpInst);
1648 // There's no need for an ORi if the immediate is 0.
1649 if (Operand.isImm() && Operand.getImm() == 0)
1652 tmpInst.setOpcode(Mips::ORi);
1653 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1654 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1655 tmpInst.addOperand(Operand);
1656 tmpInst.setLoc(IDLoc);
1657 Instructions.push_back(tmpInst);
1660 template <bool PerformShift>
1661 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1662 SmallVectorImpl<MCInst> &Instructions) {
1663 createLShiftOri<PerformShift>(MCOperand::CreateImm(Value), RegNo, IDLoc,
1668 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1669 SmallVectorImpl<MCInst> &Instructions) {
1670 // Create a JALR instruction which is going to replace the pseudo-JAL.
1672 JalrInst.setLoc(IDLoc);
1673 const MCOperand FirstRegOp = Inst.getOperand(0);
1674 const unsigned Opcode = Inst.getOpcode();
1676 if (Opcode == Mips::JalOneReg) {
1677 // jal $rs => jalr $rs
1678 if (inMicroMipsMode()) {
1679 JalrInst.setOpcode(Mips::JALR16_MM);
1680 JalrInst.addOperand(FirstRegOp);
1682 JalrInst.setOpcode(Mips::JALR);
1683 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1684 JalrInst.addOperand(FirstRegOp);
1686 } else if (Opcode == Mips::JalTwoReg) {
1687 // jal $rd, $rs => jalr $rd, $rs
1688 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1689 JalrInst.addOperand(FirstRegOp);
1690 const MCOperand SecondRegOp = Inst.getOperand(1);
1691 JalrInst.addOperand(SecondRegOp);
1693 Instructions.push_back(JalrInst);
1695 // If .set reorder is active, emit a NOP after it.
1696 if (AssemblerOptions.back()->isReorder()) {
1697 // This is a 32-bit NOP because these 2 pseudo-instructions
1698 // do not have a short delay slot.
1700 NopInst.setOpcode(Mips::SLL);
1701 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1702 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1703 NopInst.addOperand(MCOperand::CreateImm(0));
1704 Instructions.push_back(NopInst);
1710 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1711 SmallVectorImpl<MCInst> &Instructions) {
1713 const MCOperand &ImmOp = Inst.getOperand(1);
1714 assert(ImmOp.isImm() && "expected immediate operand kind");
1715 const MCOperand &RegOp = Inst.getOperand(0);
1716 assert(RegOp.isReg() && "expected register operand kind");
1718 int64_t ImmValue = ImmOp.getImm();
1719 unsigned Reg = RegOp.getReg();
1720 tmpInst.setLoc(IDLoc);
1721 // FIXME: gas has a special case for values that are 000...1111, which
1722 // becomes a li -1 and then a dsrl
1723 if (0 <= ImmValue && ImmValue <= 65535) {
1724 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1725 // li d,j => ori d,$zero,j
1726 tmpInst.setOpcode(Mips::ORi);
1727 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1728 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1729 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1730 Instructions.push_back(tmpInst);
1731 } else if (ImmValue < 0 && ImmValue >= -32768) {
1732 // For negative signed 16-bit values (-32768 <= j < 0):
1733 // li d,j => addiu d,$zero,j
1734 tmpInst.setOpcode(Mips::ADDiu);
1735 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1736 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1737 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1738 Instructions.push_back(tmpInst);
1739 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1740 // For all other values which are representable as a 32-bit integer:
1741 // li d,j => lui d,hi16(j)
1743 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1744 uint16_t Bits15To0 = ImmValue & 0xffff;
1746 tmpInst.setOpcode(Mips::LUi);
1747 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1748 tmpInst.addOperand(MCOperand::CreateImm(Bits31To16));
1749 Instructions.push_back(tmpInst);
1750 createLShiftOri<false>(Bits15To0, Reg, IDLoc, Instructions);
1751 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1753 Error(IDLoc, "instruction requires a 64-bit architecture");
1757 // <------- lo32 ------>
1758 // <------- hi32 ------>
1759 // <- hi16 -> <- lo16 ->
1760 // _________________________________
1762 // | 16-bits | 16-bits | 16-bits |
1763 // |__________|__________|__________|
1765 // For any 64-bit value that is representable as a 48-bit integer:
1766 // li d,j => lui d,hi16(j)
1767 // ori d,d,hi16(lo32(j))
1769 // ori d,d,lo16(lo32(j))
1770 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1771 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1772 uint16_t Bits15To0 = ImmValue & 0xffff;
1774 tmpInst.setOpcode(Mips::LUi);
1775 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1776 tmpInst.addOperand(MCOperand::CreateImm(Bits47To32));
1777 Instructions.push_back(tmpInst);
1778 createLShiftOri<false>(Bits31To16, Reg, IDLoc, Instructions);
1779 createLShiftOri<true>(Bits15To0, Reg, IDLoc, Instructions);
1782 Error(IDLoc, "instruction requires a 64-bit architecture");
1786 // <------- hi32 ------> <------- lo32 ------>
1787 // <- hi16 -> <- lo16 ->
1788 // ___________________________________________
1790 // | 16-bits | 16-bits | 16-bits | 16-bits |
1791 // |__________|__________|__________|__________|
1793 // For all other values which are representable as a 64-bit integer:
1794 // li d,j => lui d,hi16(j)
1795 // ori d,d,lo16(hi32(j))
1797 // ori d,d,hi16(lo32(j))
1799 // ori d,d,lo16(lo32(j))
1800 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1801 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1802 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1803 uint16_t Bits15To0 = ImmValue & 0xffff;
1805 tmpInst.setOpcode(Mips::LUi);
1806 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1807 tmpInst.addOperand(MCOperand::CreateImm(Bits63To48));
1808 Instructions.push_back(tmpInst);
1809 createLShiftOri<false>(Bits47To32, Reg, IDLoc, Instructions);
1810 createLShiftOri<true>(Bits31To16, Reg, IDLoc, Instructions);
1811 createLShiftOri<true>(Bits15To0, Reg, IDLoc, Instructions);
1817 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1818 SmallVectorImpl<MCInst> &Instructions) {
1820 const MCOperand &ImmOp = Inst.getOperand(2);
1821 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1822 "expected immediate operand kind");
1823 if (!ImmOp.isImm()) {
1824 expandLoadAddressSym(Inst, IDLoc, Instructions);
1827 const MCOperand &SrcRegOp = Inst.getOperand(1);
1828 assert(SrcRegOp.isReg() && "expected register operand kind");
1829 const MCOperand &DstRegOp = Inst.getOperand(0);
1830 assert(DstRegOp.isReg() && "expected register operand kind");
1831 int ImmValue = ImmOp.getImm();
1832 if (-32768 <= ImmValue && ImmValue <= 65535) {
1833 // For -32768 <= j <= 65535.
1834 // la d,j(s) => addiu d,s,j
1835 tmpInst.setOpcode(Mips::ADDiu);
1836 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1837 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1838 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1839 Instructions.push_back(tmpInst);
1841 // For any other value of j that is representable as a 32-bit integer.
1842 // la d,j(s) => lui d,hi16(j)
1845 tmpInst.setOpcode(Mips::LUi);
1846 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1847 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1848 Instructions.push_back(tmpInst);
1850 tmpInst.setOpcode(Mips::ORi);
1851 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1852 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1853 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1854 Instructions.push_back(tmpInst);
1856 tmpInst.setOpcode(Mips::ADDu);
1857 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1858 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1859 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1860 Instructions.push_back(tmpInst);
1866 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1867 SmallVectorImpl<MCInst> &Instructions) {
1869 const MCOperand &ImmOp = Inst.getOperand(1);
1870 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1871 "expected immediate operand kind");
1872 if (!ImmOp.isImm()) {
1873 expandLoadAddressSym(Inst, IDLoc, Instructions);
1876 const MCOperand &RegOp = Inst.getOperand(0);
1877 assert(RegOp.isReg() && "expected register operand kind");
1878 int ImmValue = ImmOp.getImm();
1879 if (-32768 <= ImmValue && ImmValue <= 65535) {
1880 // For -32768 <= j <= 65535.
1881 // la d,j => addiu d,$zero,j
1882 tmpInst.setOpcode(Mips::ADDiu);
1883 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1884 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1885 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1886 Instructions.push_back(tmpInst);
1888 // For any other value of j that is representable as a 32-bit integer.
1889 // la d,j => lui d,hi16(j)
1891 tmpInst.setOpcode(Mips::LUi);
1892 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1893 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1894 Instructions.push_back(tmpInst);
1896 tmpInst.setOpcode(Mips::ORi);
1897 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1898 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1899 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1900 Instructions.push_back(tmpInst);
1906 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1907 SmallVectorImpl<MCInst> &Instructions) {
1908 // FIXME: If we do have a valid at register to use, we should generate a
1909 // slightly shorter sequence here.
1911 int ExprOperandNo = 1;
1912 // Sometimes the assembly parser will get the immediate expression as
1913 // a $zero + an immediate.
1914 if (Inst.getNumOperands() == 3) {
1915 assert(Inst.getOperand(1).getReg() ==
1916 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1919 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1920 assert(SymOp.isExpr() && "expected symbol operand kind");
1921 const MCOperand &RegOp = Inst.getOperand(0);
1922 unsigned RegNo = RegOp.getReg();
1923 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1924 const MCSymbolRefExpr *HiExpr =
1925 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1926 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1927 const MCSymbolRefExpr *LoExpr =
1928 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1929 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1931 // If it's a 64-bit architecture, expand to:
1932 // la d,sym => lui d,highest(sym)
1933 // ori d,d,higher(sym)
1935 // ori d,d,hi16(sym)
1937 // ori d,d,lo16(sym)
1938 const MCSymbolRefExpr *HighestExpr =
1939 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1940 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1941 const MCSymbolRefExpr *HigherExpr =
1942 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1943 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1945 tmpInst.setOpcode(Mips::LUi);
1946 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1947 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1948 Instructions.push_back(tmpInst);
1950 createLShiftOri<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1952 createLShiftOri<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1954 createLShiftOri<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1957 // Otherwise, expand to:
1958 // la d,sym => lui d,hi16(sym)
1959 // ori d,d,lo16(sym)
1960 tmpInst.setOpcode(Mips::LUi);
1961 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1962 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1963 Instructions.push_back(tmpInst);
1965 createLShiftOri<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1970 bool MipsAsmParser::expandUncondBranchMMPseudo(
1971 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1972 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1973 "unexpected number of operands");
1975 MCOperand Offset = Inst.getOperand(0);
1976 if (Offset.isExpr()) {
1978 Inst.setOpcode(Mips::BEQ_MM);
1979 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1980 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1981 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1983 assert(Offset.isImm() && "expected immediate operand kind");
1984 if (isIntN(11, Offset.getImm())) {
1985 // If offset fits into 11 bits then this instruction becomes microMIPS
1986 // 16-bit unconditional branch instruction.
1987 Inst.setOpcode(Mips::B16_MM);
1989 if (!isIntN(17, Offset.getImm()))
1990 Error(IDLoc, "branch target out of range");
1991 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1992 Error(IDLoc, "branch to misaligned address");
1994 Inst.setOpcode(Mips::BEQ_MM);
1995 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1996 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1997 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
2000 Instructions.push_back(Inst);
2002 // If .set reorder is active, emit a NOP after the branch instruction.
2003 if (AssemblerOptions.back()->isReorder())
2004 createNop(true, IDLoc, Instructions);
2009 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2010 SmallVectorImpl<MCInst> &Instructions,
2011 bool isLoad, bool isImmOpnd) {
2012 const MCSymbolRefExpr *SR;
2014 unsigned ImmOffset, HiOffset, LoOffset;
2015 const MCExpr *ExprOffset;
2017 // 1st operand is either the source or destination register.
2018 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2019 unsigned RegOpNum = Inst.getOperand(0).getReg();
2020 // 2nd operand is the base register.
2021 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2022 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2023 // 3rd operand is either an immediate or expression.
2025 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2026 ImmOffset = Inst.getOperand(2).getImm();
2027 LoOffset = ImmOffset & 0x0000ffff;
2028 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2029 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2030 if (LoOffset & 0x8000)
2033 ExprOffset = Inst.getOperand(2).getExpr();
2034 // All instructions will have the same location.
2035 TempInst.setLoc(IDLoc);
2036 // These are some of the types of expansions we perform here:
2037 // 1) lw $8, sym => lui $8, %hi(sym)
2038 // lw $8, %lo(sym)($8)
2039 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2041 // lw $8, %lo(offset)($9)
2042 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2044 // lw $8, %lo(offset)($at)
2045 // 4) sw $8, sym => lui $at, %hi(sym)
2046 // sw $8, %lo(sym)($at)
2047 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2049 // sw $8, %lo(offset)($at)
2050 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2051 // ldc1 $f0, %lo(sym)($at)
2053 // For load instructions we can use the destination register as a temporary
2054 // if base and dst are different (examples 1 and 2) and if the base register
2055 // is general purpose otherwise we must use $at (example 6) and error if it's
2056 // not available. For stores we must use $at (examples 4 and 5) because we
2057 // must not clobber the source register setting up the offset.
2058 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2059 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2060 unsigned RegClassIDOp0 =
2061 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2062 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2063 (RegClassIDOp0 == Mips::GPR64RegClassID);
2064 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2065 TmpRegNum = RegOpNum;
2067 // At this point we need AT to perform the expansions and we exit if it is
2069 TmpRegNum = getATReg(IDLoc);
2074 TempInst.setOpcode(Mips::LUi);
2075 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2077 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2079 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2080 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2081 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2082 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2084 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2086 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2087 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2090 // Add the instruction to the list.
2091 Instructions.push_back(TempInst);
2092 // Prepare TempInst for next instruction.
2094 // Add temp register to base.
2095 if (BaseRegNum != Mips::ZERO) {
2096 TempInst.setOpcode(Mips::ADDu);
2097 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2098 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2099 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2100 Instructions.push_back(TempInst);
2103 // And finally, create original instruction with low part
2104 // of offset and new base.
2105 TempInst.setOpcode(Inst.getOpcode());
2106 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2107 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2109 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2111 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2112 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2113 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2115 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2117 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2118 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2121 Instructions.push_back(TempInst);
2126 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2127 SmallVectorImpl<MCInst> &Instructions) {
2128 unsigned OpNum = Inst.getNumOperands();
2129 unsigned Opcode = Inst.getOpcode();
2130 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2132 assert (Inst.getOperand(OpNum - 1).isImm() &&
2133 Inst.getOperand(OpNum - 2).isReg() &&
2134 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2136 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2137 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2138 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2139 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2140 // It can be implemented as SWM16 or LWM16 instruction.
2141 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2143 Inst.setOpcode(NewOpcode);
2144 Instructions.push_back(Inst);
2148 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2149 SmallVectorImpl<MCInst> &Instructions) {
2151 if (hasShortDelaySlot) {
2152 NopInst.setOpcode(Mips::MOVE16_MM);
2153 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2154 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2156 NopInst.setOpcode(Mips::SLL);
2157 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2158 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2159 NopInst.addOperand(MCOperand::CreateImm(0));
2161 Instructions.push_back(NopInst);
2164 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2165 // As described by the Mips32r2 spec, the registers Rd and Rs for
2166 // jalr.hb must be different.
2167 unsigned Opcode = Inst.getOpcode();
2169 if (Opcode == Mips::JALR_HB &&
2170 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2171 return Match_RequiresDifferentSrcAndDst;
2173 return Match_Success;
2176 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2177 OperandVector &Operands,
2179 uint64_t &ErrorInfo,
2180 bool MatchingInlineAsm) {
2183 SmallVector<MCInst, 8> Instructions;
2184 unsigned MatchResult =
2185 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2187 switch (MatchResult) {
2188 case Match_Success: {
2189 if (processInstruction(Inst, IDLoc, Instructions))
2191 for (unsigned i = 0; i < Instructions.size(); i++)
2192 Out.EmitInstruction(Instructions[i], STI);
2195 case Match_MissingFeature:
2196 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2198 case Match_InvalidOperand: {
2199 SMLoc ErrorLoc = IDLoc;
2200 if (ErrorInfo != ~0ULL) {
2201 if (ErrorInfo >= Operands.size())
2202 return Error(IDLoc, "too few operands for instruction");
2204 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2205 if (ErrorLoc == SMLoc())
2209 return Error(ErrorLoc, "invalid operand for instruction");
2211 case Match_MnemonicFail:
2212 return Error(IDLoc, "invalid instruction");
2213 case Match_RequiresDifferentSrcAndDst:
2214 return Error(IDLoc, "source and destination must be different");
2217 llvm_unreachable("Implement any new match types added!");
2220 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2221 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2222 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2223 ") without \".set noat\"");
2227 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2228 SMRange Range, bool ShowColors) {
2229 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2230 Range, SMFixIt(Range, FixMsg),
2234 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2237 CC = StringSwitch<unsigned>(Name)
2273 if (!(isABI_N32() || isABI_N64()))
2276 if (12 <= CC && CC <= 15) {
2277 // Name is one of t4-t7
2278 AsmToken RegTok = getLexer().peekTok();
2279 SMRange RegRange = RegTok.getLocRange();
2281 StringRef FixedName = StringSwitch<StringRef>(Name)
2287 assert(FixedName != "" && "Register name is not one of t4-t7.");
2289 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2290 "Did you mean $" + FixedName + "?", RegRange);
2293 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2294 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2295 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2296 if (8 <= CC && CC <= 11)
2300 CC = StringSwitch<unsigned>(Name)
2312 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2315 CC = StringSwitch<unsigned>(Name)
2316 .Case("hwr_cpunum", 0)
2317 .Case("hwr_synci_step", 1)
2319 .Case("hwr_ccres", 3)
2320 .Case("hwr_ulr", 29)
2326 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2328 if (Name[0] == 'f') {
2329 StringRef NumString = Name.substr(1);
2331 if (NumString.getAsInteger(10, IntVal))
2332 return -1; // This is not an integer.
2333 if (IntVal > 31) // Maximum index for fpu register.
2340 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2342 if (Name.startswith("fcc")) {
2343 StringRef NumString = Name.substr(3);
2345 if (NumString.getAsInteger(10, IntVal))
2346 return -1; // This is not an integer.
2347 if (IntVal > 7) // There are only 8 fcc registers.
2354 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2356 if (Name.startswith("ac")) {
2357 StringRef NumString = Name.substr(2);
2359 if (NumString.getAsInteger(10, IntVal))
2360 return -1; // This is not an integer.
2361 if (IntVal > 3) // There are only 3 acc registers.
2368 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2371 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2380 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2383 CC = StringSwitch<unsigned>(Name)
2386 .Case("msaaccess", 2)
2388 .Case("msamodify", 4)
2389 .Case("msarequest", 5)
2391 .Case("msaunmap", 7)
2397 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2398 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2400 reportParseError(Loc,
2401 "pseudo-instruction requires $at, which is not available");
2404 unsigned AT = getReg(
2405 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2409 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2410 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2413 unsigned MipsAsmParser::getGPR(int RegNo) {
2414 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2418 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2420 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2423 return getReg(RegClass, RegNum);
2426 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2427 MCAsmParser &Parser = getParser();
2428 DEBUG(dbgs() << "parseOperand\n");
2430 // Check if the current operand has a custom associated parser, if so, try to
2431 // custom parse the operand, or fallback to the general approach.
2432 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2433 if (ResTy == MatchOperand_Success)
2435 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2436 // there was a match, but an error occurred, in which case, just return that
2437 // the operand parsing failed.
2438 if (ResTy == MatchOperand_ParseFail)
2441 DEBUG(dbgs() << ".. Generic Parser\n");
2443 switch (getLexer().getKind()) {
2445 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2447 case AsmToken::Dollar: {
2448 // Parse the register.
2449 SMLoc S = Parser.getTok().getLoc();
2451 // Almost all registers have been parsed by custom parsers. There is only
2452 // one exception to this. $zero (and it's alias $0) will reach this point
2453 // for div, divu, and similar instructions because it is not an operand
2454 // to the instruction definition but an explicit register. Special case
2455 // this situation for now.
2456 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2459 // Maybe it is a symbol reference.
2460 StringRef Identifier;
2461 if (Parser.parseIdentifier(Identifier))
2464 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2465 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2466 // Otherwise create a symbol reference.
2468 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2470 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2473 // Else drop to expression parsing.
2474 case AsmToken::LParen:
2475 case AsmToken::Minus:
2476 case AsmToken::Plus:
2477 case AsmToken::Integer:
2478 case AsmToken::Tilde:
2479 case AsmToken::String: {
2480 DEBUG(dbgs() << ".. generic integer\n");
2481 OperandMatchResultTy ResTy = parseImm(Operands);
2482 return ResTy != MatchOperand_Success;
2484 case AsmToken::Percent: {
2485 // It is a symbol reference or constant expression.
2486 const MCExpr *IdVal;
2487 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2488 if (parseRelocOperand(IdVal))
2491 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2493 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2495 } // case AsmToken::Percent
2496 } // switch(getLexer().getKind())
2500 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2501 StringRef RelocStr) {
2503 // Check the type of the expression.
2504 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2505 // It's a constant, evaluate reloc value.
2507 switch (getVariantKind(RelocStr)) {
2508 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2509 // Get the 1st 16-bits.
2510 Val = MCE->getValue() & 0xffff;
2512 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2513 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2514 // 16 bits being negative.
2515 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2517 case MCSymbolRefExpr::VK_Mips_HIGHER:
2518 // Get the 3rd 16-bits.
2519 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2521 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2522 // Get the 4th 16-bits.
2523 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2526 report_fatal_error("unsupported reloc value");
2528 return MCConstantExpr::Create(Val, getContext());
2531 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2532 // It's a symbol, create a symbolic expression from the symbol.
2533 StringRef Symbol = MSRE->getSymbol().getName();
2534 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2535 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2539 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2540 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2542 // Try to create target expression.
2543 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2544 return MipsMCExpr::Create(VK, Expr, getContext());
2546 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2547 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2548 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2552 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2553 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2554 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2557 // Just return the original expression.
2561 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2563 switch (Expr->getKind()) {
2564 case MCExpr::Constant:
2566 case MCExpr::SymbolRef:
2567 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2568 case MCExpr::Binary:
2569 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2570 if (!isEvaluated(BE->getLHS()))
2572 return isEvaluated(BE->getRHS());
2575 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2576 case MCExpr::Target:
2582 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2583 MCAsmParser &Parser = getParser();
2584 Parser.Lex(); // Eat the % token.
2585 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2586 if (Tok.isNot(AsmToken::Identifier))
2589 std::string Str = Tok.getIdentifier();
2591 Parser.Lex(); // Eat the identifier.
2592 // Now make an expression from the rest of the operand.
2593 const MCExpr *IdVal;
2596 if (getLexer().getKind() == AsmToken::LParen) {
2598 Parser.Lex(); // Eat the '(' token.
2599 if (getLexer().getKind() == AsmToken::Percent) {
2600 Parser.Lex(); // Eat the % token.
2601 const AsmToken &nextTok = Parser.getTok();
2602 if (nextTok.isNot(AsmToken::Identifier))
2605 Str += nextTok.getIdentifier();
2606 Parser.Lex(); // Eat the identifier.
2607 if (getLexer().getKind() != AsmToken::LParen)
2612 if (getParser().parseParenExpression(IdVal, EndLoc))
2615 while (getLexer().getKind() == AsmToken::RParen)
2616 Parser.Lex(); // Eat the ')' token.
2619 return true; // Parenthesis must follow the relocation operand.
2621 Res = evaluateRelocExpr(IdVal, Str);
2625 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2627 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2628 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2629 if (ResTy == MatchOperand_Success) {
2630 assert(Operands.size() == 1);
2631 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2632 StartLoc = Operand.getStartLoc();
2633 EndLoc = Operand.getEndLoc();
2635 // AFAIK, we only support numeric registers and named GPR's in CFI
2637 // Don't worry about eating tokens before failing. Using an unrecognised
2638 // register is a parse error.
2639 if (Operand.isGPRAsmReg()) {
2640 // Resolve to GPR32 or GPR64 appropriately.
2641 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2644 return (RegNo == (unsigned)-1);
2647 assert(Operands.size() == 0);
2648 return (RegNo == (unsigned)-1);
2651 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2652 MCAsmParser &Parser = getParser();
2656 while (getLexer().getKind() == AsmToken::LParen)
2659 switch (getLexer().getKind()) {
2662 case AsmToken::Identifier:
2663 case AsmToken::LParen:
2664 case AsmToken::Integer:
2665 case AsmToken::Minus:
2666 case AsmToken::Plus:
2668 Result = getParser().parseParenExpression(Res, S);
2670 Result = (getParser().parseExpression(Res));
2671 while (getLexer().getKind() == AsmToken::RParen)
2674 case AsmToken::Percent:
2675 Result = parseRelocOperand(Res);
2680 MipsAsmParser::OperandMatchResultTy
2681 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2682 MCAsmParser &Parser = getParser();
2683 DEBUG(dbgs() << "parseMemOperand\n");
2684 const MCExpr *IdVal = nullptr;
2686 bool isParenExpr = false;
2687 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2688 // First operand is the offset.
2689 S = Parser.getTok().getLoc();
2691 if (getLexer().getKind() == AsmToken::LParen) {
2696 if (getLexer().getKind() != AsmToken::Dollar) {
2697 if (parseMemOffset(IdVal, isParenExpr))
2698 return MatchOperand_ParseFail;
2700 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2701 if (Tok.isNot(AsmToken::LParen)) {
2702 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2703 if (Mnemonic.getToken() == "la") {
2705 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2706 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2707 return MatchOperand_Success;
2709 if (Tok.is(AsmToken::EndOfStatement)) {
2711 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2713 // Zero register assumed, add a memory operand with ZERO as its base.
2714 // "Base" will be managed by k_Memory.
2715 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2718 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2719 return MatchOperand_Success;
2721 Error(Parser.getTok().getLoc(), "'(' expected");
2722 return MatchOperand_ParseFail;
2725 Parser.Lex(); // Eat the '(' token.
2728 Res = parseAnyRegister(Operands);
2729 if (Res != MatchOperand_Success)
2732 if (Parser.getTok().isNot(AsmToken::RParen)) {
2733 Error(Parser.getTok().getLoc(), "')' expected");
2734 return MatchOperand_ParseFail;
2737 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2739 Parser.Lex(); // Eat the ')' token.
2742 IdVal = MCConstantExpr::Create(0, getContext());
2744 // Replace the register operand with the memory operand.
2745 std::unique_ptr<MipsOperand> op(
2746 static_cast<MipsOperand *>(Operands.back().release()));
2747 // Remove the register from the operands.
2748 // "op" will be managed by k_Memory.
2749 Operands.pop_back();
2750 // Add the memory operand.
2751 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2753 if (IdVal->EvaluateAsAbsolute(Imm))
2754 IdVal = MCConstantExpr::Create(Imm, getContext());
2755 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2756 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2760 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2761 return MatchOperand_Success;
2764 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2765 MCAsmParser &Parser = getParser();
2766 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2768 SMLoc S = Parser.getTok().getLoc();
2770 if (Sym->isVariable())
2771 Expr = Sym->getVariableValue();
2774 if (Expr->getKind() == MCExpr::SymbolRef) {
2775 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2776 StringRef DefSymbol = Ref->getSymbol().getName();
2777 if (DefSymbol.startswith("$")) {
2778 OperandMatchResultTy ResTy =
2779 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2780 if (ResTy == MatchOperand_Success) {
2783 } else if (ResTy == MatchOperand_ParseFail)
2784 llvm_unreachable("Should never ParseFail");
2787 } else if (Expr->getKind() == MCExpr::Constant) {
2789 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2791 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2798 MipsAsmParser::OperandMatchResultTy
2799 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2800 StringRef Identifier,
2802 int Index = matchCPURegisterName(Identifier);
2804 Operands.push_back(MipsOperand::createGPRReg(
2805 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2806 return MatchOperand_Success;
2809 Index = matchHWRegsRegisterName(Identifier);
2811 Operands.push_back(MipsOperand::createHWRegsReg(
2812 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2813 return MatchOperand_Success;
2816 Index = matchFPURegisterName(Identifier);
2818 Operands.push_back(MipsOperand::createFGRReg(
2819 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2820 return MatchOperand_Success;
2823 Index = matchFCCRegisterName(Identifier);
2825 Operands.push_back(MipsOperand::createFCCReg(
2826 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2827 return MatchOperand_Success;
2830 Index = matchACRegisterName(Identifier);
2832 Operands.push_back(MipsOperand::createACCReg(
2833 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2834 return MatchOperand_Success;
2837 Index = matchMSA128RegisterName(Identifier);
2839 Operands.push_back(MipsOperand::createMSA128Reg(
2840 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2841 return MatchOperand_Success;
2844 Index = matchMSA128CtrlRegisterName(Identifier);
2846 Operands.push_back(MipsOperand::createMSACtrlReg(
2847 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2848 return MatchOperand_Success;
2851 return MatchOperand_NoMatch;
2854 MipsAsmParser::OperandMatchResultTy
2855 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2856 MCAsmParser &Parser = getParser();
2857 auto Token = Parser.getLexer().peekTok(false);
2859 if (Token.is(AsmToken::Identifier)) {
2860 DEBUG(dbgs() << ".. identifier\n");
2861 StringRef Identifier = Token.getIdentifier();
2862 OperandMatchResultTy ResTy =
2863 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2865 } else if (Token.is(AsmToken::Integer)) {
2866 DEBUG(dbgs() << ".. integer\n");
2867 Operands.push_back(MipsOperand::createNumericReg(
2868 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2870 return MatchOperand_Success;
2873 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2875 return MatchOperand_NoMatch;
2878 MipsAsmParser::OperandMatchResultTy
2879 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2880 MCAsmParser &Parser = getParser();
2881 DEBUG(dbgs() << "parseAnyRegister\n");
2883 auto Token = Parser.getTok();
2885 SMLoc S = Token.getLoc();
2887 if (Token.isNot(AsmToken::Dollar)) {
2888 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2889 if (Token.is(AsmToken::Identifier)) {
2890 if (searchSymbolAlias(Operands))
2891 return MatchOperand_Success;
2893 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2894 return MatchOperand_NoMatch;
2896 DEBUG(dbgs() << ".. $\n");
2898 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2899 if (ResTy == MatchOperand_Success) {
2901 Parser.Lex(); // identifier
2906 MipsAsmParser::OperandMatchResultTy
2907 MipsAsmParser::parseImm(OperandVector &Operands) {
2908 MCAsmParser &Parser = getParser();
2909 switch (getLexer().getKind()) {
2911 return MatchOperand_NoMatch;
2912 case AsmToken::LParen:
2913 case AsmToken::Minus:
2914 case AsmToken::Plus:
2915 case AsmToken::Integer:
2916 case AsmToken::Tilde:
2917 case AsmToken::String:
2921 const MCExpr *IdVal;
2922 SMLoc S = Parser.getTok().getLoc();
2923 if (getParser().parseExpression(IdVal))
2924 return MatchOperand_ParseFail;
2926 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2927 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2928 return MatchOperand_Success;
2931 MipsAsmParser::OperandMatchResultTy
2932 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2933 MCAsmParser &Parser = getParser();
2934 DEBUG(dbgs() << "parseJumpTarget\n");
2936 SMLoc S = getLexer().getLoc();
2938 // Integers and expressions are acceptable
2939 OperandMatchResultTy ResTy = parseImm(Operands);
2940 if (ResTy != MatchOperand_NoMatch)
2943 // Registers are a valid target and have priority over symbols.
2944 ResTy = parseAnyRegister(Operands);
2945 if (ResTy != MatchOperand_NoMatch)
2948 const MCExpr *Expr = nullptr;
2949 if (Parser.parseExpression(Expr)) {
2950 // We have no way of knowing if a symbol was consumed so we must ParseFail
2951 return MatchOperand_ParseFail;
2954 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2955 return MatchOperand_Success;
2958 MipsAsmParser::OperandMatchResultTy
2959 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2960 MCAsmParser &Parser = getParser();
2961 const MCExpr *IdVal;
2962 // If the first token is '$' we may have register operand.
2963 if (Parser.getTok().is(AsmToken::Dollar))
2964 return MatchOperand_NoMatch;
2965 SMLoc S = Parser.getTok().getLoc();
2966 if (getParser().parseExpression(IdVal))
2967 return MatchOperand_ParseFail;
2968 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2969 assert(MCE && "Unexpected MCExpr type.");
2970 int64_t Val = MCE->getValue();
2971 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2972 Operands.push_back(MipsOperand::CreateImm(
2973 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2974 return MatchOperand_Success;
2977 MipsAsmParser::OperandMatchResultTy
2978 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2979 MCAsmParser &Parser = getParser();
2980 switch (getLexer().getKind()) {
2982 return MatchOperand_NoMatch;
2983 case AsmToken::LParen:
2984 case AsmToken::Plus:
2985 case AsmToken::Minus:
2986 case AsmToken::Integer:
2991 SMLoc S = Parser.getTok().getLoc();
2993 if (getParser().parseExpression(Expr))
2994 return MatchOperand_ParseFail;
2997 if (!Expr->EvaluateAsAbsolute(Val)) {
2998 Error(S, "expected immediate value");
2999 return MatchOperand_ParseFail;
3002 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3003 // and because the CPU always adds one to the immediate field, the allowed
3004 // range becomes 1..4. We'll only check the range here and will deal
3005 // with the addition/subtraction when actually decoding/encoding
3007 if (Val < 1 || Val > 4) {
3008 Error(S, "immediate not in range (1..4)");
3009 return MatchOperand_ParseFail;
3013 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3014 return MatchOperand_Success;
3017 MipsAsmParser::OperandMatchResultTy
3018 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3019 MCAsmParser &Parser = getParser();
3020 SmallVector<unsigned, 10> Regs;
3022 unsigned PrevReg = Mips::NoRegister;
3023 bool RegRange = false;
3024 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3026 if (Parser.getTok().isNot(AsmToken::Dollar))
3027 return MatchOperand_ParseFail;
3029 SMLoc S = Parser.getTok().getLoc();
3030 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3031 SMLoc E = getLexer().getLoc();
3032 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3033 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3035 // Remove last register operand because registers from register range
3036 // should be inserted first.
3037 if (RegNo == Mips::RA) {
3038 Regs.push_back(RegNo);
3040 unsigned TmpReg = PrevReg + 1;
3041 while (TmpReg <= RegNo) {
3042 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3043 Error(E, "invalid register operand");
3044 return MatchOperand_ParseFail;
3048 Regs.push_back(TmpReg++);
3054 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3055 (RegNo != Mips::RA)) {
3056 Error(E, "$16 or $31 expected");
3057 return MatchOperand_ParseFail;
3058 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3059 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3060 Error(E, "invalid register operand");
3061 return MatchOperand_ParseFail;
3062 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3063 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3064 Error(E, "consecutive register numbers expected");
3065 return MatchOperand_ParseFail;
3068 Regs.push_back(RegNo);
3071 if (Parser.getTok().is(AsmToken::Minus))
3074 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3075 !Parser.getTok().isNot(AsmToken::Comma)) {
3076 Error(E, "',' or '-' expected");
3077 return MatchOperand_ParseFail;
3080 Lex(); // Consume comma or minus
3081 if (Parser.getTok().isNot(AsmToken::Dollar))
3087 SMLoc E = Parser.getTok().getLoc();
3088 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3089 parseMemOperand(Operands);
3090 return MatchOperand_Success;
3093 MipsAsmParser::OperandMatchResultTy
3094 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3095 MCAsmParser &Parser = getParser();
3097 SMLoc S = Parser.getTok().getLoc();
3098 if (parseAnyRegister(Operands) != MatchOperand_Success)
3099 return MatchOperand_ParseFail;
3101 SMLoc E = Parser.getTok().getLoc();
3102 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3103 unsigned Reg = Op.getGPR32Reg();
3104 Operands.pop_back();
3105 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3106 return MatchOperand_Success;
3109 MipsAsmParser::OperandMatchResultTy
3110 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3111 MCAsmParser &Parser = getParser();
3112 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3113 SmallVector<unsigned, 10> Regs;
3115 if (Parser.getTok().isNot(AsmToken::Dollar))
3116 return MatchOperand_ParseFail;
3118 SMLoc S = Parser.getTok().getLoc();
3120 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3121 return MatchOperand_ParseFail;
3123 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3124 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3125 Regs.push_back(RegNo);
3127 SMLoc E = Parser.getTok().getLoc();
3128 if (Parser.getTok().isNot(AsmToken::Comma)) {
3129 Error(E, "',' expected");
3130 return MatchOperand_ParseFail;
3136 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3137 return MatchOperand_ParseFail;
3139 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3140 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3141 Regs.push_back(RegNo);
3143 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3145 return MatchOperand_Success;
3148 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3150 MCSymbolRefExpr::VariantKind VK =
3151 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3152 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3153 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3154 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3155 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3156 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3157 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3158 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3159 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3160 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3161 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3162 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3163 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3164 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3165 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3166 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3167 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3168 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3169 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3170 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3171 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3172 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3173 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3174 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3175 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3176 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3177 .Default(MCSymbolRefExpr::VK_None);
3179 assert(VK != MCSymbolRefExpr::VK_None);
3184 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3186 /// ::= '(', register, ')'
3187 /// handle it before we iterate so we don't get tripped up by the lack of
3189 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3190 MCAsmParser &Parser = getParser();
3191 if (getLexer().is(AsmToken::LParen)) {
3193 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3195 if (parseOperand(Operands, Name)) {
3196 SMLoc Loc = getLexer().getLoc();
3197 Parser.eatToEndOfStatement();
3198 return Error(Loc, "unexpected token in argument list");
3200 if (Parser.getTok().isNot(AsmToken::RParen)) {
3201 SMLoc Loc = getLexer().getLoc();
3202 Parser.eatToEndOfStatement();
3203 return Error(Loc, "unexpected token, expected ')'");
3206 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3212 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3213 /// either one of these.
3214 /// ::= '[', register, ']'
3215 /// ::= '[', integer, ']'
3216 /// handle it before we iterate so we don't get tripped up by the lack of
3218 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3219 OperandVector &Operands) {
3220 MCAsmParser &Parser = getParser();
3221 if (getLexer().is(AsmToken::LBrac)) {
3223 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3225 if (parseOperand(Operands, Name)) {
3226 SMLoc Loc = getLexer().getLoc();
3227 Parser.eatToEndOfStatement();
3228 return Error(Loc, "unexpected token in argument list");
3230 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3231 SMLoc Loc = getLexer().getLoc();
3232 Parser.eatToEndOfStatement();
3233 return Error(Loc, "unexpected token, expected ']'");
3236 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3242 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3243 SMLoc NameLoc, OperandVector &Operands) {
3244 MCAsmParser &Parser = getParser();
3245 DEBUG(dbgs() << "ParseInstruction\n");
3247 // We have reached first instruction, module directive are now forbidden.
3248 getTargetStreamer().forbidModuleDirective();
3250 // Check if we have valid mnemonic
3251 if (!mnemonicIsValid(Name, 0)) {
3252 Parser.eatToEndOfStatement();
3253 return Error(NameLoc, "unknown instruction");
3255 // First operand in MCInst is instruction mnemonic.
3256 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3258 // Read the remaining operands.
3259 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3260 // Read the first operand.
3261 if (parseOperand(Operands, Name)) {
3262 SMLoc Loc = getLexer().getLoc();
3263 Parser.eatToEndOfStatement();
3264 return Error(Loc, "unexpected token in argument list");
3266 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3268 // AFAIK, parenthesis suffixes are never on the first operand
3270 while (getLexer().is(AsmToken::Comma)) {
3271 Parser.Lex(); // Eat the comma.
3272 // Parse and remember the operand.
3273 if (parseOperand(Operands, Name)) {
3274 SMLoc Loc = getLexer().getLoc();
3275 Parser.eatToEndOfStatement();
3276 return Error(Loc, "unexpected token in argument list");
3278 // Parse bracket and parenthesis suffixes before we iterate
3279 if (getLexer().is(AsmToken::LBrac)) {
3280 if (parseBracketSuffix(Name, Operands))
3282 } else if (getLexer().is(AsmToken::LParen) &&
3283 parseParenSuffix(Name, Operands))
3287 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3288 SMLoc Loc = getLexer().getLoc();
3289 Parser.eatToEndOfStatement();
3290 return Error(Loc, "unexpected token in argument list");
3292 Parser.Lex(); // Consume the EndOfStatement.
3296 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3297 MCAsmParser &Parser = getParser();
3298 SMLoc Loc = getLexer().getLoc();
3299 Parser.eatToEndOfStatement();
3300 return Error(Loc, ErrorMsg);
3303 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3304 return Error(Loc, ErrorMsg);
3307 bool MipsAsmParser::parseSetNoAtDirective() {
3308 MCAsmParser &Parser = getParser();
3309 // Line should look like: ".set noat".
3311 // Set the $at register to $0.
3312 AssemblerOptions.back()->setATRegIndex(0);
3314 Parser.Lex(); // Eat "noat".
3316 // If this is not the end of the statement, report an error.
3317 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3318 reportParseError("unexpected token, expected end of statement");
3322 getTargetStreamer().emitDirectiveSetNoAt();
3323 Parser.Lex(); // Consume the EndOfStatement.
3327 bool MipsAsmParser::parseSetAtDirective() {
3328 // Line can be: ".set at", which sets $at to $1
3329 // or ".set at=$reg", which sets $at to $reg.
3330 MCAsmParser &Parser = getParser();
3331 Parser.Lex(); // Eat "at".
3333 if (getLexer().is(AsmToken::EndOfStatement)) {
3334 // No register was specified, so we set $at to $1.
3335 AssemblerOptions.back()->setATRegIndex(1);
3337 getTargetStreamer().emitDirectiveSetAt();
3338 Parser.Lex(); // Consume the EndOfStatement.
3342 if (getLexer().isNot(AsmToken::Equal)) {
3343 reportParseError("unexpected token, expected equals sign");
3346 Parser.Lex(); // Eat "=".
3348 if (getLexer().isNot(AsmToken::Dollar)) {
3349 if (getLexer().is(AsmToken::EndOfStatement)) {
3350 reportParseError("no register specified");
3353 reportParseError("unexpected token, expected dollar sign '$'");
3357 Parser.Lex(); // Eat "$".
3359 // Find out what "reg" is.
3361 const AsmToken &Reg = Parser.getTok();
3362 if (Reg.is(AsmToken::Identifier)) {
3363 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3364 } else if (Reg.is(AsmToken::Integer)) {
3365 AtRegNo = Reg.getIntVal();
3367 reportParseError("unexpected token, expected identifier or integer");
3371 // Check if $reg is a valid register. If it is, set $at to $reg.
3372 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3373 reportParseError("invalid register");
3376 Parser.Lex(); // Eat "reg".
3378 // If this is not the end of the statement, report an error.
3379 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3380 reportParseError("unexpected token, expected end of statement");
3384 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3386 Parser.Lex(); // Consume the EndOfStatement.
3390 bool MipsAsmParser::parseSetReorderDirective() {
3391 MCAsmParser &Parser = getParser();
3393 // If this is not the end of the statement, report an error.
3394 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3395 reportParseError("unexpected token, expected end of statement");
3398 AssemblerOptions.back()->setReorder();
3399 getTargetStreamer().emitDirectiveSetReorder();
3400 Parser.Lex(); // Consume the EndOfStatement.
3404 bool MipsAsmParser::parseSetNoReorderDirective() {
3405 MCAsmParser &Parser = getParser();
3407 // If this is not the end of the statement, report an error.
3408 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3409 reportParseError("unexpected token, expected end of statement");
3412 AssemblerOptions.back()->setNoReorder();
3413 getTargetStreamer().emitDirectiveSetNoReorder();
3414 Parser.Lex(); // Consume the EndOfStatement.
3418 bool MipsAsmParser::parseSetMacroDirective() {
3419 MCAsmParser &Parser = getParser();
3421 // If this is not the end of the statement, report an error.
3422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3423 reportParseError("unexpected token, expected end of statement");
3426 AssemblerOptions.back()->setMacro();
3427 Parser.Lex(); // Consume the EndOfStatement.
3431 bool MipsAsmParser::parseSetNoMacroDirective() {
3432 MCAsmParser &Parser = getParser();
3434 // If this is not the end of the statement, report an error.
3435 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3436 reportParseError("unexpected token, expected end of statement");
3439 if (AssemblerOptions.back()->isReorder()) {
3440 reportParseError("`noreorder' must be set before `nomacro'");
3443 AssemblerOptions.back()->setNoMacro();
3444 Parser.Lex(); // Consume the EndOfStatement.
3448 bool MipsAsmParser::parseSetMsaDirective() {
3449 MCAsmParser &Parser = getParser();
3452 // If this is not the end of the statement, report an error.
3453 if (getLexer().isNot(AsmToken::EndOfStatement))
3454 return reportParseError("unexpected token, expected end of statement");
3456 setFeatureBits(Mips::FeatureMSA, "msa");
3457 getTargetStreamer().emitDirectiveSetMsa();
3461 bool MipsAsmParser::parseSetNoMsaDirective() {
3462 MCAsmParser &Parser = getParser();
3465 // If this is not the end of the statement, report an error.
3466 if (getLexer().isNot(AsmToken::EndOfStatement))
3467 return reportParseError("unexpected token, expected end of statement");
3469 clearFeatureBits(Mips::FeatureMSA, "msa");
3470 getTargetStreamer().emitDirectiveSetNoMsa();
3474 bool MipsAsmParser::parseSetNoDspDirective() {
3475 MCAsmParser &Parser = getParser();
3476 Parser.Lex(); // Eat "nodsp".
3478 // If this is not the end of the statement, report an error.
3479 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3480 reportParseError("unexpected token, expected end of statement");
3484 clearFeatureBits(Mips::FeatureDSP, "dsp");
3485 getTargetStreamer().emitDirectiveSetNoDsp();
3489 bool MipsAsmParser::parseSetMips16Directive() {
3490 MCAsmParser &Parser = getParser();
3491 Parser.Lex(); // Eat "mips16".
3493 // If this is not the end of the statement, report an error.
3494 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3495 reportParseError("unexpected token, expected end of statement");
3499 setFeatureBits(Mips::FeatureMips16, "mips16");
3500 getTargetStreamer().emitDirectiveSetMips16();
3501 Parser.Lex(); // Consume the EndOfStatement.
3505 bool MipsAsmParser::parseSetNoMips16Directive() {
3506 MCAsmParser &Parser = getParser();
3507 Parser.Lex(); // Eat "nomips16".
3509 // If this is not the end of the statement, report an error.
3510 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3511 reportParseError("unexpected token, expected end of statement");
3515 clearFeatureBits(Mips::FeatureMips16, "mips16");
3516 getTargetStreamer().emitDirectiveSetNoMips16();
3517 Parser.Lex(); // Consume the EndOfStatement.
3521 bool MipsAsmParser::parseSetFpDirective() {
3522 MCAsmParser &Parser = getParser();
3523 MipsABIFlagsSection::FpABIKind FpAbiVal;
3524 // Line can be: .set fp=32
3527 Parser.Lex(); // Eat fp token
3528 AsmToken Tok = Parser.getTok();
3529 if (Tok.isNot(AsmToken::Equal)) {
3530 reportParseError("unexpected token, expected equals sign '='");
3533 Parser.Lex(); // Eat '=' token.
3534 Tok = Parser.getTok();
3536 if (!parseFpABIValue(FpAbiVal, ".set"))
3539 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3540 reportParseError("unexpected token, expected end of statement");
3543 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3544 Parser.Lex(); // Consume the EndOfStatement.
3548 bool MipsAsmParser::parseSetPopDirective() {
3549 MCAsmParser &Parser = getParser();
3550 SMLoc Loc = getLexer().getLoc();
3553 if (getLexer().isNot(AsmToken::EndOfStatement))
3554 return reportParseError("unexpected token, expected end of statement");
3556 // Always keep an element on the options "stack" to prevent the user
3557 // from changing the initial options. This is how we remember them.
3558 if (AssemblerOptions.size() == 2)
3559 return reportParseError(Loc, ".set pop with no .set push");
3561 AssemblerOptions.pop_back();
3562 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3564 getTargetStreamer().emitDirectiveSetPop();
3568 bool MipsAsmParser::parseSetPushDirective() {
3569 MCAsmParser &Parser = getParser();
3571 if (getLexer().isNot(AsmToken::EndOfStatement))
3572 return reportParseError("unexpected token, expected end of statement");
3574 // Create a copy of the current assembler options environment and push it.
3575 AssemblerOptions.push_back(
3576 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3578 getTargetStreamer().emitDirectiveSetPush();
3582 bool MipsAsmParser::parseSetAssignment() {
3584 const MCExpr *Value;
3585 MCAsmParser &Parser = getParser();
3587 if (Parser.parseIdentifier(Name))
3588 reportParseError("expected identifier after .set");
3590 if (getLexer().isNot(AsmToken::Comma))
3591 return reportParseError("unexpected token, expected comma");
3594 if (Parser.parseExpression(Value))
3595 return reportParseError("expected valid expression after comma");
3597 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3598 Sym->setVariableValue(Value);
3603 bool MipsAsmParser::parseSetMips0Directive() {
3604 MCAsmParser &Parser = getParser();
3606 if (getLexer().isNot(AsmToken::EndOfStatement))
3607 return reportParseError("unexpected token, expected end of statement");
3609 // Reset assembler options to their initial values.
3610 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3611 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3613 getTargetStreamer().emitDirectiveSetMips0();
3617 bool MipsAsmParser::parseSetArchDirective() {
3618 MCAsmParser &Parser = getParser();
3620 if (getLexer().isNot(AsmToken::Equal))
3621 return reportParseError("unexpected token, expected equals sign");
3625 if (Parser.parseIdentifier(Arch))
3626 return reportParseError("expected arch identifier");
3628 StringRef ArchFeatureName =
3629 StringSwitch<StringRef>(Arch)
3630 .Case("mips1", "mips1")
3631 .Case("mips2", "mips2")
3632 .Case("mips3", "mips3")
3633 .Case("mips4", "mips4")
3634 .Case("mips5", "mips5")
3635 .Case("mips32", "mips32")
3636 .Case("mips32r2", "mips32r2")
3637 .Case("mips32r3", "mips32r3")
3638 .Case("mips32r5", "mips32r5")
3639 .Case("mips32r6", "mips32r6")
3640 .Case("mips64", "mips64")
3641 .Case("mips64r2", "mips64r2")
3642 .Case("mips64r3", "mips64r3")
3643 .Case("mips64r5", "mips64r5")
3644 .Case("mips64r6", "mips64r6")
3645 .Case("cnmips", "cnmips")
3646 .Case("r4000", "mips3") // This is an implementation of Mips3.
3649 if (ArchFeatureName.empty())
3650 return reportParseError("unsupported architecture");
3652 selectArch(ArchFeatureName);
3653 getTargetStreamer().emitDirectiveSetArch(Arch);
3657 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3658 MCAsmParser &Parser = getParser();
3660 if (getLexer().isNot(AsmToken::EndOfStatement))
3661 return reportParseError("unexpected token, expected end of statement");
3665 llvm_unreachable("Unimplemented feature");
3666 case Mips::FeatureDSP:
3667 setFeatureBits(Mips::FeatureDSP, "dsp");
3668 getTargetStreamer().emitDirectiveSetDsp();
3670 case Mips::FeatureMicroMips:
3671 getTargetStreamer().emitDirectiveSetMicroMips();
3673 case Mips::FeatureMips1:
3674 selectArch("mips1");
3675 getTargetStreamer().emitDirectiveSetMips1();
3677 case Mips::FeatureMips2:
3678 selectArch("mips2");
3679 getTargetStreamer().emitDirectiveSetMips2();
3681 case Mips::FeatureMips3:
3682 selectArch("mips3");
3683 getTargetStreamer().emitDirectiveSetMips3();
3685 case Mips::FeatureMips4:
3686 selectArch("mips4");
3687 getTargetStreamer().emitDirectiveSetMips4();
3689 case Mips::FeatureMips5:
3690 selectArch("mips5");
3691 getTargetStreamer().emitDirectiveSetMips5();
3693 case Mips::FeatureMips32:
3694 selectArch("mips32");
3695 getTargetStreamer().emitDirectiveSetMips32();
3697 case Mips::FeatureMips32r2:
3698 selectArch("mips32r2");
3699 getTargetStreamer().emitDirectiveSetMips32R2();
3701 case Mips::FeatureMips32r3:
3702 selectArch("mips32r3");
3703 getTargetStreamer().emitDirectiveSetMips32R3();
3705 case Mips::FeatureMips32r5:
3706 selectArch("mips32r5");
3707 getTargetStreamer().emitDirectiveSetMips32R5();
3709 case Mips::FeatureMips32r6:
3710 selectArch("mips32r6");
3711 getTargetStreamer().emitDirectiveSetMips32R6();
3713 case Mips::FeatureMips64:
3714 selectArch("mips64");
3715 getTargetStreamer().emitDirectiveSetMips64();
3717 case Mips::FeatureMips64r2:
3718 selectArch("mips64r2");
3719 getTargetStreamer().emitDirectiveSetMips64R2();
3721 case Mips::FeatureMips64r3:
3722 selectArch("mips64r3");
3723 getTargetStreamer().emitDirectiveSetMips64R3();
3725 case Mips::FeatureMips64r5:
3726 selectArch("mips64r5");
3727 getTargetStreamer().emitDirectiveSetMips64R5();
3729 case Mips::FeatureMips64r6:
3730 selectArch("mips64r6");
3731 getTargetStreamer().emitDirectiveSetMips64R6();
3737 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3738 MCAsmParser &Parser = getParser();
3739 if (getLexer().isNot(AsmToken::Comma)) {
3740 SMLoc Loc = getLexer().getLoc();
3741 Parser.eatToEndOfStatement();
3742 return Error(Loc, ErrorStr);
3745 Parser.Lex(); // Eat the comma.
3749 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3750 if (AssemblerOptions.back()->isReorder())
3751 Warning(Loc, ".cpload should be inside a noreorder section");
3753 if (inMips16Mode()) {
3754 reportParseError(".cpload is not supported in Mips16 mode");
3758 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3759 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3760 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3761 reportParseError("expected register containing function address");
3765 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3766 if (!RegOpnd.isGPRAsmReg()) {
3767 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3771 // If this is not the end of the statement, report an error.
3772 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3773 reportParseError("unexpected token, expected end of statement");
3777 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3781 bool MipsAsmParser::parseDirectiveCPSetup() {
3782 MCAsmParser &Parser = getParser();
3785 bool SaveIsReg = true;
3787 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3788 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3789 if (ResTy == MatchOperand_NoMatch) {
3790 reportParseError("expected register containing function address");
3791 Parser.eatToEndOfStatement();
3795 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3796 if (!FuncRegOpnd.isGPRAsmReg()) {
3797 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3798 Parser.eatToEndOfStatement();
3802 FuncReg = FuncRegOpnd.getGPR32Reg();
3805 if (!eatComma("unexpected token, expected comma"))
3808 ResTy = parseAnyRegister(TmpReg);
3809 if (ResTy == MatchOperand_NoMatch) {
3810 const AsmToken &Tok = Parser.getTok();
3811 if (Tok.is(AsmToken::Integer)) {
3812 Save = Tok.getIntVal();
3816 reportParseError("expected save register or stack offset");
3817 Parser.eatToEndOfStatement();
3821 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3822 if (!SaveOpnd.isGPRAsmReg()) {
3823 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3824 Parser.eatToEndOfStatement();
3827 Save = SaveOpnd.getGPR32Reg();
3830 if (!eatComma("unexpected token, expected comma"))
3834 if (Parser.parseExpression(Expr)) {
3835 reportParseError("expected expression");
3839 if (Expr->getKind() != MCExpr::SymbolRef) {
3840 reportParseError("expected symbol");
3843 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3845 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3850 bool MipsAsmParser::parseDirectiveNaN() {
3851 MCAsmParser &Parser = getParser();
3852 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3853 const AsmToken &Tok = Parser.getTok();
3855 if (Tok.getString() == "2008") {
3857 getTargetStreamer().emitDirectiveNaN2008();
3859 } else if (Tok.getString() == "legacy") {
3861 getTargetStreamer().emitDirectiveNaNLegacy();
3865 // If we don't recognize the option passed to the .nan
3866 // directive (e.g. no option or unknown option), emit an error.
3867 reportParseError("invalid option in .nan directive");
3871 bool MipsAsmParser::parseDirectiveSet() {
3872 MCAsmParser &Parser = getParser();
3873 // Get the next token.
3874 const AsmToken &Tok = Parser.getTok();
3876 if (Tok.getString() == "noat") {
3877 return parseSetNoAtDirective();
3878 } else if (Tok.getString() == "at") {
3879 return parseSetAtDirective();
3880 } else if (Tok.getString() == "arch") {
3881 return parseSetArchDirective();
3882 } else if (Tok.getString() == "fp") {
3883 return parseSetFpDirective();
3884 } else if (Tok.getString() == "pop") {
3885 return parseSetPopDirective();
3886 } else if (Tok.getString() == "push") {
3887 return parseSetPushDirective();
3888 } else if (Tok.getString() == "reorder") {
3889 return parseSetReorderDirective();
3890 } else if (Tok.getString() == "noreorder") {
3891 return parseSetNoReorderDirective();
3892 } else if (Tok.getString() == "macro") {
3893 return parseSetMacroDirective();
3894 } else if (Tok.getString() == "nomacro") {
3895 return parseSetNoMacroDirective();
3896 } else if (Tok.getString() == "mips16") {
3897 return parseSetMips16Directive();
3898 } else if (Tok.getString() == "nomips16") {
3899 return parseSetNoMips16Directive();
3900 } else if (Tok.getString() == "nomicromips") {
3901 getTargetStreamer().emitDirectiveSetNoMicroMips();
3902 Parser.eatToEndOfStatement();
3904 } else if (Tok.getString() == "micromips") {
3905 return parseSetFeature(Mips::FeatureMicroMips);
3906 } else if (Tok.getString() == "mips0") {
3907 return parseSetMips0Directive();
3908 } else if (Tok.getString() == "mips1") {
3909 return parseSetFeature(Mips::FeatureMips1);
3910 } else if (Tok.getString() == "mips2") {
3911 return parseSetFeature(Mips::FeatureMips2);
3912 } else if (Tok.getString() == "mips3") {
3913 return parseSetFeature(Mips::FeatureMips3);
3914 } else if (Tok.getString() == "mips4") {
3915 return parseSetFeature(Mips::FeatureMips4);
3916 } else if (Tok.getString() == "mips5") {
3917 return parseSetFeature(Mips::FeatureMips5);
3918 } else if (Tok.getString() == "mips32") {
3919 return parseSetFeature(Mips::FeatureMips32);
3920 } else if (Tok.getString() == "mips32r2") {
3921 return parseSetFeature(Mips::FeatureMips32r2);
3922 } else if (Tok.getString() == "mips32r3") {
3923 return parseSetFeature(Mips::FeatureMips32r3);
3924 } else if (Tok.getString() == "mips32r5") {
3925 return parseSetFeature(Mips::FeatureMips32r5);
3926 } else if (Tok.getString() == "mips32r6") {
3927 return parseSetFeature(Mips::FeatureMips32r6);
3928 } else if (Tok.getString() == "mips64") {
3929 return parseSetFeature(Mips::FeatureMips64);
3930 } else if (Tok.getString() == "mips64r2") {
3931 return parseSetFeature(Mips::FeatureMips64r2);
3932 } else if (Tok.getString() == "mips64r3") {
3933 return parseSetFeature(Mips::FeatureMips64r3);
3934 } else if (Tok.getString() == "mips64r5") {
3935 return parseSetFeature(Mips::FeatureMips64r5);
3936 } else if (Tok.getString() == "mips64r6") {
3937 return parseSetFeature(Mips::FeatureMips64r6);
3938 } else if (Tok.getString() == "dsp") {
3939 return parseSetFeature(Mips::FeatureDSP);
3940 } else if (Tok.getString() == "nodsp") {
3941 return parseSetNoDspDirective();
3942 } else if (Tok.getString() == "msa") {
3943 return parseSetMsaDirective();
3944 } else if (Tok.getString() == "nomsa") {
3945 return parseSetNoMsaDirective();
3947 // It is just an identifier, look for an assignment.
3948 parseSetAssignment();
3955 /// parseDataDirective
3956 /// ::= .word [ expression (, expression)* ]
3957 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3958 MCAsmParser &Parser = getParser();
3959 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3961 const MCExpr *Value;
3962 if (getParser().parseExpression(Value))
3965 getParser().getStreamer().EmitValue(Value, Size);
3967 if (getLexer().is(AsmToken::EndOfStatement))
3970 if (getLexer().isNot(AsmToken::Comma))
3971 return Error(L, "unexpected token, expected comma");
3980 /// parseDirectiveGpWord
3981 /// ::= .gpword local_sym
3982 bool MipsAsmParser::parseDirectiveGpWord() {
3983 MCAsmParser &Parser = getParser();
3984 const MCExpr *Value;
3985 // EmitGPRel32Value requires an expression, so we are using base class
3986 // method to evaluate the expression.
3987 if (getParser().parseExpression(Value))
3989 getParser().getStreamer().EmitGPRel32Value(Value);
3991 if (getLexer().isNot(AsmToken::EndOfStatement))
3992 return Error(getLexer().getLoc(),
3993 "unexpected token, expected end of statement");
3994 Parser.Lex(); // Eat EndOfStatement token.
3998 /// parseDirectiveGpDWord
3999 /// ::= .gpdword local_sym
4000 bool MipsAsmParser::parseDirectiveGpDWord() {
4001 MCAsmParser &Parser = getParser();
4002 const MCExpr *Value;
4003 // EmitGPRel64Value requires an expression, so we are using base class
4004 // method to evaluate the expression.
4005 if (getParser().parseExpression(Value))
4007 getParser().getStreamer().EmitGPRel64Value(Value);
4009 if (getLexer().isNot(AsmToken::EndOfStatement))
4010 return Error(getLexer().getLoc(),
4011 "unexpected token, expected end of statement");
4012 Parser.Lex(); // Eat EndOfStatement token.
4016 bool MipsAsmParser::parseDirectiveOption() {
4017 MCAsmParser &Parser = getParser();
4018 // Get the option token.
4019 AsmToken Tok = Parser.getTok();
4020 // At the moment only identifiers are supported.
4021 if (Tok.isNot(AsmToken::Identifier)) {
4022 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4023 Parser.eatToEndOfStatement();
4027 StringRef Option = Tok.getIdentifier();
4029 if (Option == "pic0") {
4030 getTargetStreamer().emitDirectiveOptionPic0();
4032 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4033 Error(Parser.getTok().getLoc(),
4034 "unexpected token, expected end of statement");
4035 Parser.eatToEndOfStatement();
4040 if (Option == "pic2") {
4041 getTargetStreamer().emitDirectiveOptionPic2();
4043 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4044 Error(Parser.getTok().getLoc(),
4045 "unexpected token, expected end of statement");
4046 Parser.eatToEndOfStatement();
4052 Warning(Parser.getTok().getLoc(),
4053 "unknown option, expected 'pic0' or 'pic2'");
4054 Parser.eatToEndOfStatement();
4058 /// parseInsnDirective
4060 bool MipsAsmParser::parseInsnDirective() {
4061 // If this is not the end of the statement, report an error.
4062 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4063 reportParseError("unexpected token, expected end of statement");
4067 // The actual label marking happens in
4068 // MipsELFStreamer::createPendingLabelRelocs().
4069 getTargetStreamer().emitDirectiveInsn();
4071 getParser().Lex(); // Eat EndOfStatement token.
4075 /// parseDirectiveModule
4076 /// ::= .module oddspreg
4077 /// ::= .module nooddspreg
4078 /// ::= .module fp=value
4079 bool MipsAsmParser::parseDirectiveModule() {
4080 MCAsmParser &Parser = getParser();
4081 MCAsmLexer &Lexer = getLexer();
4082 SMLoc L = Lexer.getLoc();
4084 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4085 // TODO : get a better message.
4086 reportParseError(".module directive must appear before any code");
4091 if (Parser.parseIdentifier(Option)) {
4092 reportParseError("expected .module option identifier");
4096 if (Option == "oddspreg") {
4097 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4098 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4100 // If this is not the end of the statement, report an error.
4101 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4102 reportParseError("unexpected token, expected end of statement");
4106 return false; // parseDirectiveModule has finished successfully.
4107 } else if (Option == "nooddspreg") {
4109 Error(L, "'.module nooddspreg' requires the O32 ABI");
4113 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4114 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4116 // If this is not the end of the statement, report an error.
4117 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4118 reportParseError("unexpected token, expected end of statement");
4122 return false; // parseDirectiveModule has finished successfully.
4123 } else if (Option == "fp") {
4124 return parseDirectiveModuleFP();
4126 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4130 /// parseDirectiveModuleFP
4134 bool MipsAsmParser::parseDirectiveModuleFP() {
4135 MCAsmParser &Parser = getParser();
4136 MCAsmLexer &Lexer = getLexer();
4138 if (Lexer.isNot(AsmToken::Equal)) {
4139 reportParseError("unexpected token, expected equals sign '='");
4142 Parser.Lex(); // Eat '=' token.
4144 MipsABIFlagsSection::FpABIKind FpABI;
4145 if (!parseFpABIValue(FpABI, ".module"))
4148 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4149 reportParseError("unexpected token, expected end of statement");
4153 // Emit appropriate flags.
4154 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4155 Parser.Lex(); // Consume the EndOfStatement.
4159 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4160 StringRef Directive) {
4161 MCAsmParser &Parser = getParser();
4162 MCAsmLexer &Lexer = getLexer();
4164 if (Lexer.is(AsmToken::Identifier)) {
4165 StringRef Value = Parser.getTok().getString();
4168 if (Value != "xx") {
4169 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4174 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4178 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4182 if (Lexer.is(AsmToken::Integer)) {
4183 unsigned Value = Parser.getTok().getIntVal();
4186 if (Value != 32 && Value != 64) {
4187 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4193 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4197 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4199 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4207 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4208 MCAsmParser &Parser = getParser();
4209 StringRef IDVal = DirectiveID.getString();
4211 if (IDVal == ".cpload")
4212 return parseDirectiveCpLoad(DirectiveID.getLoc());
4213 if (IDVal == ".dword") {
4214 parseDataDirective(8, DirectiveID.getLoc());
4217 if (IDVal == ".ent") {
4218 StringRef SymbolName;
4220 if (Parser.parseIdentifier(SymbolName)) {
4221 reportParseError("expected identifier after .ent");
4225 // There's an undocumented extension that allows an integer to
4226 // follow the name of the procedure which AFAICS is ignored by GAS.
4227 // Example: .ent foo,2
4228 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4229 if (getLexer().isNot(AsmToken::Comma)) {
4230 // Even though we accept this undocumented extension for compatibility
4231 // reasons, the additional integer argument does not actually change
4232 // the behaviour of the '.ent' directive, so we would like to discourage
4233 // its use. We do this by not referring to the extended version in
4234 // error messages which are not directly related to its use.
4235 reportParseError("unexpected token, expected end of statement");
4238 Parser.Lex(); // Eat the comma.
4239 const MCExpr *DummyNumber;
4240 int64_t DummyNumberVal;
4241 // If the user was explicitly trying to use the extended version,
4242 // we still give helpful extension-related error messages.
4243 if (Parser.parseExpression(DummyNumber)) {
4244 reportParseError("expected number after comma");
4247 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4248 reportParseError("expected an absolute expression after comma");
4253 // If this is not the end of the statement, report an error.
4254 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4255 reportParseError("unexpected token, expected end of statement");
4259 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4261 getTargetStreamer().emitDirectiveEnt(*Sym);
4266 if (IDVal == ".end") {
4267 StringRef SymbolName;
4269 if (Parser.parseIdentifier(SymbolName)) {
4270 reportParseError("expected identifier after .end");
4274 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4275 reportParseError("unexpected token, expected end of statement");
4279 if (CurrentFn == nullptr) {
4280 reportParseError(".end used without .ent");
4284 if ((SymbolName != CurrentFn->getName())) {
4285 reportParseError(".end symbol does not match .ent symbol");
4289 getTargetStreamer().emitDirectiveEnd(SymbolName);
4290 CurrentFn = nullptr;
4294 if (IDVal == ".frame") {
4295 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4296 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4297 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4298 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4299 reportParseError("expected stack register");
4303 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4304 if (!StackRegOpnd.isGPRAsmReg()) {
4305 reportParseError(StackRegOpnd.getStartLoc(),
4306 "expected general purpose register");
4309 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4311 if (Parser.getTok().is(AsmToken::Comma))
4314 reportParseError("unexpected token, expected comma");
4318 // Parse the frame size.
4319 const MCExpr *FrameSize;
4320 int64_t FrameSizeVal;
4322 if (Parser.parseExpression(FrameSize)) {
4323 reportParseError("expected frame size value");
4327 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4328 reportParseError("frame size not an absolute expression");
4332 if (Parser.getTok().is(AsmToken::Comma))
4335 reportParseError("unexpected token, expected comma");
4339 // Parse the return register.
4341 ResTy = parseAnyRegister(TmpReg);
4342 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4343 reportParseError("expected return register");
4347 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4348 if (!ReturnRegOpnd.isGPRAsmReg()) {
4349 reportParseError(ReturnRegOpnd.getStartLoc(),
4350 "expected general purpose register");
4354 // If this is not the end of the statement, report an error.
4355 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4356 reportParseError("unexpected token, expected end of statement");
4360 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4361 ReturnRegOpnd.getGPR32Reg());
4365 if (IDVal == ".set") {
4366 return parseDirectiveSet();
4369 if (IDVal == ".mask" || IDVal == ".fmask") {
4370 // .mask bitmask, frame_offset
4371 // bitmask: One bit for each register used.
4372 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4373 // first register is expected to be saved.
4375 // .mask 0x80000000, -4
4376 // .fmask 0x80000000, -4
4379 // Parse the bitmask
4380 const MCExpr *BitMask;
4383 if (Parser.parseExpression(BitMask)) {
4384 reportParseError("expected bitmask value");
4388 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4389 reportParseError("bitmask not an absolute expression");
4393 if (Parser.getTok().is(AsmToken::Comma))
4396 reportParseError("unexpected token, expected comma");
4400 // Parse the frame_offset
4401 const MCExpr *FrameOffset;
4402 int64_t FrameOffsetVal;
4404 if (Parser.parseExpression(FrameOffset)) {
4405 reportParseError("expected frame offset value");
4409 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4410 reportParseError("frame offset not an absolute expression");
4414 // If this is not the end of the statement, report an error.
4415 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4416 reportParseError("unexpected token, expected end of statement");
4420 if (IDVal == ".mask")
4421 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4423 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4427 if (IDVal == ".nan")
4428 return parseDirectiveNaN();
4430 if (IDVal == ".gpword") {
4431 parseDirectiveGpWord();
4435 if (IDVal == ".gpdword") {
4436 parseDirectiveGpDWord();
4440 if (IDVal == ".word") {
4441 parseDataDirective(4, DirectiveID.getLoc());
4445 if (IDVal == ".option")
4446 return parseDirectiveOption();
4448 if (IDVal == ".abicalls") {
4449 getTargetStreamer().emitDirectiveAbiCalls();
4450 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4451 Error(Parser.getTok().getLoc(),
4452 "unexpected token, expected end of statement");
4454 Parser.eatToEndOfStatement();
4459 if (IDVal == ".cpsetup")
4460 return parseDirectiveCPSetup();
4462 if (IDVal == ".module")
4463 return parseDirectiveModule();
4465 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4466 return parseInternalDirectiveReallowModule();
4468 if (IDVal == ".insn")
4469 return parseInsnDirective();
4474 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4475 // If this is not the end of the statement, report an error.
4476 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4477 reportParseError("unexpected token, expected end of statement");
4481 getTargetStreamer().reallowModuleDirective();
4483 getParser().Lex(); // Eat EndOfStatement token.
4487 extern "C" void LLVMInitializeMipsAsmParser() {
4488 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4489 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4490 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4491 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4494 #define GET_REGISTER_MATCHER
4495 #define GET_MATCHER_IMPLEMENTATION
4496 #include "MipsGenAsmMatcher.inc"