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->getATRegNum();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegNum() const { return ATReg; }
57 bool setATReg(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();
224 bool parseSetAtDirective();
225 bool parseSetNoAtDirective();
226 bool parseSetMacroDirective();
227 bool parseSetNoMacroDirective();
228 bool parseSetMsaDirective();
229 bool parseSetNoMsaDirective();
230 bool parseSetNoDspDirective();
231 bool parseSetReorderDirective();
232 bool parseSetNoReorderDirective();
233 bool parseSetMips16Directive();
234 bool parseSetNoMips16Directive();
235 bool parseSetFpDirective();
236 bool parseSetPopDirective();
237 bool parseSetPushDirective();
239 bool parseSetAssignment();
241 bool parseDataDirective(unsigned Size, SMLoc L);
242 bool parseDirectiveGpWord();
243 bool parseDirectiveGpDWord();
244 bool parseDirectiveModule();
245 bool parseDirectiveModuleFP();
246 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
247 StringRef Directive);
249 bool parseInternalDirectiveReallowModule();
251 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
253 bool eatComma(StringRef ErrorStr);
255 int matchCPURegisterName(StringRef Symbol);
257 int matchHWRegsRegisterName(StringRef Symbol);
259 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
261 int matchFPURegisterName(StringRef Name);
263 int matchFCCRegisterName(StringRef Name);
265 int matchACRegisterName(StringRef Name);
267 int matchMSA128RegisterName(StringRef Name);
269 int matchMSA128CtrlRegisterName(StringRef Name);
271 unsigned getReg(int RC, int RegNo);
273 unsigned getGPR(int RegNo);
275 int getATReg(SMLoc Loc);
277 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
278 SmallVectorImpl<MCInst> &Instructions);
280 // Helper function that checks if the value of a vector index is within the
281 // boundaries of accepted values for each RegisterKind
282 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
283 bool validateMSAIndex(int Val, int RegKind);
285 // Selects a new architecture by updating the FeatureBits with the necessary
286 // info including implied dependencies.
287 // Internally, it clears all the feature bits related to *any* architecture
288 // and selects the new one using the ToggleFeature functionality of the
289 // MCSubtargetInfo object that handles implied dependencies. The reason we
290 // clear all the arch related bits manually is because ToggleFeature only
291 // clears the features that imply the feature being cleared and not the
292 // features implied by the feature being cleared. This is easier to see
294 // --------------------------------------------------
295 // | Feature | Implies |
296 // | -------------------------------------------------|
297 // | FeatureMips1 | None |
298 // | FeatureMips2 | FeatureMips1 |
299 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
300 // | FeatureMips4 | FeatureMips3 |
302 // --------------------------------------------------
304 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
305 // FeatureMipsGP64 | FeatureMips1)
306 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
307 void selectArch(StringRef ArchFeature) {
308 uint64_t FeatureBits = STI.getFeatureBits();
309 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
310 STI.setFeatureBits(FeatureBits);
311 setAvailableFeatures(
312 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
313 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
316 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
317 if (!(STI.getFeatureBits() & Feature)) {
318 setAvailableFeatures(
319 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
321 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
324 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
325 if (STI.getFeatureBits() & Feature) {
326 setAvailableFeatures(
327 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
329 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
333 enum MipsMatchResultTy {
334 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
335 #define GET_OPERAND_DIAGNOSTIC_TYPES
336 #include "MipsGenAsmMatcher.inc"
337 #undef GET_OPERAND_DIAGNOSTIC_TYPES
341 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
342 const MCInstrInfo &MII, const MCTargetOptions &Options)
343 : MCTargetAsmParser(), STI(sti),
344 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
345 sti.getCPU(), Options)) {
346 MCAsmParserExtension::Initialize(parser);
348 // Initialize the set of available features.
349 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
351 // Remember the initial assembler options. The user can not modify these.
352 AssemblerOptions.push_back(
353 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
355 // Create an assembler options environment for the user to modify.
356 AssemblerOptions.push_back(
357 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
359 getTargetStreamer().updateABIInfo(*this);
361 if (!isABI_O32() && !useOddSPReg() != 0)
362 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
367 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
368 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
370 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
371 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
372 const MipsABIInfo &getABI() const { return ABI; }
373 bool isABI_N32() const { return ABI.IsN32(); }
374 bool isABI_N64() const { return ABI.IsN64(); }
375 bool isABI_O32() const { return ABI.IsO32(); }
376 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
378 bool useOddSPReg() const {
379 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
382 bool inMicroMipsMode() const {
383 return STI.getFeatureBits() & Mips::FeatureMicroMips;
385 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
386 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
387 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
388 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
389 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
390 bool hasMips32() const {
391 return (STI.getFeatureBits() & Mips::FeatureMips32);
393 bool hasMips64() const {
394 return (STI.getFeatureBits() & Mips::FeatureMips64);
396 bool hasMips32r2() const {
397 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
399 bool hasMips64r2() const {
400 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
402 bool hasMips32r3() const {
403 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
405 bool hasMips64r3() const {
406 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
408 bool hasMips32r5() const {
409 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
411 bool hasMips64r5() const {
412 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
414 bool hasMips32r6() const {
415 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
417 bool hasMips64r6() const {
418 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
420 bool hasCnMips() const {
421 return (STI.getFeatureBits() & Mips::FeatureCnMips);
423 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
424 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
425 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
427 bool inMips16Mode() const {
428 return STI.getFeatureBits() & Mips::FeatureMips16;
430 // TODO: see how can we get this info.
431 bool abiUsesSoftFloat() const { return false; }
433 /// Warn if RegNo is the current assembler temporary.
434 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
440 /// MipsOperand - Instances of this class represent a parsed Mips machine
442 class MipsOperand : public MCParsedAsmOperand {
444 /// Broad categories of register classes
445 /// The exact class is finalized by the render method.
447 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
448 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
450 RegKind_FCC = 4, /// FCC
451 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
452 RegKind_MSACtrl = 16, /// MSA control registers
453 RegKind_COP2 = 32, /// COP2
454 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
456 RegKind_CCR = 128, /// CCR
457 RegKind_HWRegs = 256, /// HWRegs
458 RegKind_COP3 = 512, /// COP3
460 /// Potentially any (e.g. $1)
461 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
462 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
463 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
468 k_Immediate, /// An immediate (possibly involving symbol references)
469 k_Memory, /// Base + Offset Memory Address
470 k_PhysRegister, /// A physical register from the Mips namespace
471 k_RegisterIndex, /// A register index in one or more RegKind.
472 k_Token, /// A simple token
473 k_RegList, /// A physical register list
474 k_RegPair /// A pair of physical register
478 MipsOperand(KindTy K, MipsAsmParser &Parser)
479 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
482 /// For diagnostics, and checking the assembler temporary
483 MipsAsmParser &AsmParser;
491 unsigned Num; /// Register Number
495 unsigned Index; /// Index into the register class
496 RegKind Kind; /// Bitfield of the kinds it could possibly be
497 const MCRegisterInfo *RegInfo;
510 SmallVector<unsigned, 10> *List;
515 struct PhysRegOp PhysReg;
516 struct RegIdxOp RegIdx;
519 struct RegListOp RegList;
522 SMLoc StartLoc, EndLoc;
524 /// Internal constructor for register kinds
525 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
526 const MCRegisterInfo *RegInfo,
528 MipsAsmParser &Parser) {
529 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
530 Op->RegIdx.Index = Index;
531 Op->RegIdx.RegInfo = RegInfo;
532 Op->RegIdx.Kind = RegKind;
539 /// Coerce the register to GPR32 and return the real register for the current
541 unsigned getGPR32Reg() const {
542 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
543 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
544 unsigned ClassID = Mips::GPR32RegClassID;
545 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
548 /// Coerce the register to GPR32 and return the real register for the current
550 unsigned getGPRMM16Reg() const {
551 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
552 unsigned ClassID = Mips::GPR32RegClassID;
553 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
556 /// Coerce the register to GPR64 and return the real register for the current
558 unsigned getGPR64Reg() const {
559 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
560 unsigned ClassID = Mips::GPR64RegClassID;
561 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
565 /// Coerce the register to AFGR64 and return the real register for the current
567 unsigned getAFGR64Reg() const {
568 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
569 if (RegIdx.Index % 2 != 0)
570 AsmParser.Warning(StartLoc, "Float register should be even.");
571 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
572 .getRegister(RegIdx.Index / 2);
575 /// Coerce the register to FGR64 and return the real register for the current
577 unsigned getFGR64Reg() const {
578 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
579 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
580 .getRegister(RegIdx.Index);
583 /// Coerce the register to FGR32 and return the real register for the current
585 unsigned getFGR32Reg() const {
586 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
587 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
588 .getRegister(RegIdx.Index);
591 /// Coerce the register to FGRH32 and return the real register for the current
593 unsigned getFGRH32Reg() const {
594 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
595 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
596 .getRegister(RegIdx.Index);
599 /// Coerce the register to FCC and return the real register for the current
601 unsigned getFCCReg() const {
602 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
603 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
604 .getRegister(RegIdx.Index);
607 /// Coerce the register to MSA128 and return the real register for the current
609 unsigned getMSA128Reg() const {
610 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
611 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
613 unsigned ClassID = Mips::MSA128BRegClassID;
614 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
617 /// Coerce the register to MSACtrl and return the real register for the
619 unsigned getMSACtrlReg() const {
620 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
621 unsigned ClassID = Mips::MSACtrlRegClassID;
622 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
625 /// Coerce the register to COP2 and return the real register for the
627 unsigned getCOP2Reg() const {
628 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
629 unsigned ClassID = Mips::COP2RegClassID;
630 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
633 /// Coerce the register to COP3 and return the real register for the
635 unsigned getCOP3Reg() const {
636 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
637 unsigned ClassID = Mips::COP3RegClassID;
638 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
641 /// Coerce the register to ACC64DSP and return the real register for the
643 unsigned getACC64DSPReg() const {
644 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
645 unsigned ClassID = Mips::ACC64DSPRegClassID;
646 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
649 /// Coerce the register to HI32DSP and return the real register for the
651 unsigned getHI32DSPReg() const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
653 unsigned ClassID = Mips::HI32DSPRegClassID;
654 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
657 /// Coerce the register to LO32DSP and return the real register for the
659 unsigned getLO32DSPReg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
661 unsigned ClassID = Mips::LO32DSPRegClassID;
662 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
665 /// Coerce the register to CCR and return the real register for the
667 unsigned getCCRReg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
669 unsigned ClassID = Mips::CCRRegClassID;
670 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
673 /// Coerce the register to HWRegs and return the real register for the
675 unsigned getHWRegsReg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
677 unsigned ClassID = Mips::HWRegsRegClassID;
678 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
682 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
683 // Add as immediate when possible. Null MCExpr = 0.
685 Inst.addOperand(MCOperand::CreateImm(0));
686 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
687 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
689 Inst.addOperand(MCOperand::CreateExpr(Expr));
692 void addRegOperands(MCInst &Inst, unsigned N) const {
693 llvm_unreachable("Use a custom parser instead");
696 /// Render the operand to an MCInst as a GPR32
697 /// Asserts if the wrong number of operands are requested, or the operand
698 /// is not a k_RegisterIndex compatible with RegKind_GPR
699 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
700 assert(N == 1 && "Invalid number of operands!");
701 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
704 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
705 assert(N == 1 && "Invalid number of operands!");
706 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
709 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
710 assert(N == 1 && "Invalid number of operands!");
711 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
714 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
715 assert(N == 1 && "Invalid number of operands!");
716 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
719 /// Render the operand to an MCInst as a GPR64
720 /// Asserts if the wrong number of operands are requested, or the operand
721 /// is not a k_RegisterIndex compatible with RegKind_GPR
722 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
723 assert(N == 1 && "Invalid number of operands!");
724 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
727 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
728 assert(N == 1 && "Invalid number of operands!");
729 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
732 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
733 assert(N == 1 && "Invalid number of operands!");
734 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
737 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
738 assert(N == 1 && "Invalid number of operands!");
739 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
740 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
741 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
742 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
746 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
747 assert(N == 1 && "Invalid number of operands!");
748 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
751 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
752 assert(N == 1 && "Invalid number of operands!");
753 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
756 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
757 assert(N == 1 && "Invalid number of operands!");
758 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
761 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
762 assert(N == 1 && "Invalid number of operands!");
763 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
766 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
767 assert(N == 1 && "Invalid number of operands!");
768 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
771 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
772 assert(N == 1 && "Invalid number of operands!");
773 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
776 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
777 assert(N == 1 && "Invalid number of operands!");
778 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
781 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
782 assert(N == 1 && "Invalid number of operands!");
783 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
786 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
787 assert(N == 1 && "Invalid number of operands!");
788 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
791 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
792 assert(N == 1 && "Invalid number of operands!");
793 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
796 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
797 assert(N == 1 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
801 void addImmOperands(MCInst &Inst, unsigned N) const {
802 assert(N == 1 && "Invalid number of operands!");
803 const MCExpr *Expr = getImm();
807 void addMemOperands(MCInst &Inst, unsigned N) const {
808 assert(N == 2 && "Invalid number of operands!");
810 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
812 const MCExpr *Expr = getMemOff();
816 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
817 assert(N == 2 && "Invalid number of operands!");
819 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
821 const MCExpr *Expr = getMemOff();
825 void addRegListOperands(MCInst &Inst, unsigned N) const {
826 assert(N == 1 && "Invalid number of operands!");
828 for (auto RegNo : getRegList())
829 Inst.addOperand(MCOperand::CreateReg(RegNo));
832 void addRegPairOperands(MCInst &Inst, unsigned N) const {
833 assert(N == 2 && "Invalid number of operands!");
834 unsigned RegNo = getRegPair();
835 Inst.addOperand(MCOperand::CreateReg(RegNo++));
836 Inst.addOperand(MCOperand::CreateReg(RegNo));
839 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
840 assert(N == 2 && "Invalid number of operands!");
841 for (auto RegNo : getRegList())
842 Inst.addOperand(MCOperand::CreateReg(RegNo));
845 bool isReg() const override {
846 // As a special case until we sort out the definition of div/divu, pretend
847 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
848 if (isGPRAsmReg() && RegIdx.Index == 0)
851 return Kind == k_PhysRegister;
853 bool isRegIdx() const { return Kind == k_RegisterIndex; }
854 bool isImm() const override { return Kind == k_Immediate; }
855 bool isConstantImm() const {
856 return isImm() && dyn_cast<MCConstantExpr>(getImm());
858 bool isToken() const override {
859 // Note: It's not possible to pretend that other operand kinds are tokens.
860 // The matcher emitter checks tokens first.
861 return Kind == k_Token;
863 bool isMem() const override { return Kind == k_Memory; }
864 bool isConstantMemOff() const {
865 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
867 template <unsigned Bits> bool isMemWithSimmOffset() const {
868 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
870 bool isMemWithGRPMM16Base() const {
871 return isMem() && getMemBase()->isMM16AsmReg();
873 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
874 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
875 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
877 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
878 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
879 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
880 && (getMemBase()->getGPR32Reg() == Mips::SP);
882 bool isRegList16() const {
886 int Size = RegList.List->size();
887 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
888 RegList.List->back() != Mips::RA)
891 int PrevReg = *RegList.List->begin();
892 for (int i = 1; i < Size - 1; i++) {
893 int Reg = (*(RegList.List))[i];
894 if ( Reg != PrevReg + 1)
901 bool isInvNum() const { return Kind == k_Immediate; }
902 bool isLSAImm() const {
903 if (!isConstantImm())
905 int64_t Val = getConstantImm();
906 return 1 <= Val && Val <= 4;
908 bool isRegList() const { return Kind == k_RegList; }
909 bool isMovePRegPair() const {
910 if (Kind != k_RegList || RegList.List->size() != 2)
913 unsigned R0 = RegList.List->front();
914 unsigned R1 = RegList.List->back();
916 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
917 (R0 == Mips::A1 && R1 == Mips::A3) ||
918 (R0 == Mips::A2 && R1 == Mips::A3) ||
919 (R0 == Mips::A0 && R1 == Mips::S5) ||
920 (R0 == Mips::A0 && R1 == Mips::S6) ||
921 (R0 == Mips::A0 && R1 == Mips::A1) ||
922 (R0 == Mips::A0 && R1 == Mips::A2) ||
923 (R0 == Mips::A0 && R1 == Mips::A3))
929 StringRef getToken() const {
930 assert(Kind == k_Token && "Invalid access!");
931 return StringRef(Tok.Data, Tok.Length);
933 bool isRegPair() const { return Kind == k_RegPair; }
935 unsigned getReg() const override {
936 // As a special case until we sort out the definition of div/divu, pretend
937 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
938 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
939 RegIdx.Kind & RegKind_GPR)
940 return getGPR32Reg(); // FIXME: GPR64 too
942 assert(Kind == k_PhysRegister && "Invalid access!");
946 const MCExpr *getImm() const {
947 assert((Kind == k_Immediate) && "Invalid access!");
951 int64_t getConstantImm() const {
952 const MCExpr *Val = getImm();
953 return static_cast<const MCConstantExpr *>(Val)->getValue();
956 MipsOperand *getMemBase() const {
957 assert((Kind == k_Memory) && "Invalid access!");
961 const MCExpr *getMemOff() const {
962 assert((Kind == k_Memory) && "Invalid access!");
966 int64_t getConstantMemOff() const {
967 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
970 const SmallVectorImpl<unsigned> &getRegList() const {
971 assert((Kind == k_RegList) && "Invalid access!");
972 return *(RegList.List);
975 unsigned getRegPair() const {
976 assert((Kind == k_RegPair) && "Invalid access!");
980 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
981 MipsAsmParser &Parser) {
982 auto Op = make_unique<MipsOperand>(k_Token, Parser);
983 Op->Tok.Data = Str.data();
984 Op->Tok.Length = Str.size();
990 /// Create a numeric register (e.g. $1). The exact register remains
991 /// unresolved until an instruction successfully matches
992 static std::unique_ptr<MipsOperand>
993 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
994 SMLoc E, MipsAsmParser &Parser) {
995 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
996 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
999 /// Create a register that is definitely a GPR.
1000 /// This is typically only used for named registers such as $gp.
1001 static std::unique_ptr<MipsOperand>
1002 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1003 MipsAsmParser &Parser) {
1004 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1007 /// Create a register that is definitely a FGR.
1008 /// This is typically only used for named registers such as $f0.
1009 static std::unique_ptr<MipsOperand>
1010 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1011 MipsAsmParser &Parser) {
1012 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1015 /// Create a register that is definitely a HWReg.
1016 /// This is typically only used for named registers such as $hwr_cpunum.
1017 static std::unique_ptr<MipsOperand>
1018 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1019 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1020 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1023 /// Create a register that is definitely an FCC.
1024 /// This is typically only used for named registers such as $fcc0.
1025 static std::unique_ptr<MipsOperand>
1026 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1027 MipsAsmParser &Parser) {
1028 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1031 /// Create a register that is definitely an ACC.
1032 /// This is typically only used for named registers such as $ac0.
1033 static std::unique_ptr<MipsOperand>
1034 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1035 MipsAsmParser &Parser) {
1036 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1039 /// Create a register that is definitely an MSA128.
1040 /// This is typically only used for named registers such as $w0.
1041 static std::unique_ptr<MipsOperand>
1042 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1043 SMLoc E, MipsAsmParser &Parser) {
1044 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1047 /// Create a register that is definitely an MSACtrl.
1048 /// This is typically only used for named registers such as $msaaccess.
1049 static std::unique_ptr<MipsOperand>
1050 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1051 SMLoc E, MipsAsmParser &Parser) {
1052 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1055 static std::unique_ptr<MipsOperand>
1056 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1057 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1064 static std::unique_ptr<MipsOperand>
1065 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1066 SMLoc E, MipsAsmParser &Parser) {
1067 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1068 Op->Mem.Base = Base.release();
1075 static std::unique_ptr<MipsOperand>
1076 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1077 MipsAsmParser &Parser) {
1078 assert (Regs.size() > 0 && "Empty list not allowed");
1080 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1081 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1082 Op->StartLoc = StartLoc;
1083 Op->EndLoc = EndLoc;
1087 static std::unique_ptr<MipsOperand>
1088 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1089 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1090 Op->RegIdx.Index = RegNo;
1096 bool isGPRAsmReg() const {
1097 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1099 bool isMM16AsmReg() const {
1100 if (!(isRegIdx() && RegIdx.Kind))
1102 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1103 || RegIdx.Index == 16 || RegIdx.Index == 17);
1105 bool isMM16AsmRegZero() const {
1106 if (!(isRegIdx() && RegIdx.Kind))
1108 return (RegIdx.Index == 0 ||
1109 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1110 RegIdx.Index == 17);
1112 bool isMM16AsmRegMoveP() const {
1113 if (!(isRegIdx() && RegIdx.Kind))
1115 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1116 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1118 bool isFGRAsmReg() const {
1119 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1120 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1122 bool isHWRegsAsmReg() const {
1123 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1125 bool isCCRAsmReg() const {
1126 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1128 bool isFCCAsmReg() const {
1129 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1131 if (!AsmParser.hasEightFccRegisters())
1132 return RegIdx.Index == 0;
1133 return RegIdx.Index <= 7;
1135 bool isACCAsmReg() const {
1136 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1138 bool isCOP2AsmReg() const {
1139 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1141 bool isCOP3AsmReg() const {
1142 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1144 bool isMSA128AsmReg() const {
1145 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1147 bool isMSACtrlAsmReg() const {
1148 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1151 /// getStartLoc - Get the location of the first token of this operand.
1152 SMLoc getStartLoc() const override { return StartLoc; }
1153 /// getEndLoc - Get the location of the last token of this operand.
1154 SMLoc getEndLoc() const override { return EndLoc; }
1156 virtual ~MipsOperand() {
1164 delete RegList.List;
1165 case k_PhysRegister:
1166 case k_RegisterIndex:
1173 void print(raw_ostream &OS) const override {
1182 Mem.Base->print(OS);
1187 case k_PhysRegister:
1188 OS << "PhysReg<" << PhysReg.Num << ">";
1190 case k_RegisterIndex:
1191 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1198 for (auto Reg : (*RegList.List))
1203 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1207 }; // class MipsOperand
1211 extern const MCInstrDesc MipsInsts[];
1213 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1214 return MipsInsts[Opcode];
1217 static bool hasShortDelaySlot(unsigned Opcode) {
1220 case Mips::JALRS_MM:
1221 case Mips::JALRS16_MM:
1222 case Mips::BGEZALS_MM:
1223 case Mips::BLTZALS_MM:
1230 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1231 SmallVectorImpl<MCInst> &Instructions) {
1232 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1236 if (MCID.isBranch() || MCID.isCall()) {
1237 const unsigned Opcode = Inst.getOpcode();
1247 assert(hasCnMips() && "instruction only valid for octeon cpus");
1254 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1255 Offset = Inst.getOperand(2);
1256 if (!Offset.isImm())
1257 break; // We'll deal with this situation later on when applying fixups.
1258 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1259 return Error(IDLoc, "branch target out of range");
1260 if (OffsetToAlignment(Offset.getImm(),
1261 1LL << (inMicroMipsMode() ? 1 : 2)))
1262 return Error(IDLoc, "branch to misaligned address");
1276 case Mips::BGEZAL_MM:
1277 case Mips::BLTZAL_MM:
1280 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1281 Offset = Inst.getOperand(1);
1282 if (!Offset.isImm())
1283 break; // We'll deal with this situation later on when applying fixups.
1284 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1285 return Error(IDLoc, "branch target out of range");
1286 if (OffsetToAlignment(Offset.getImm(),
1287 1LL << (inMicroMipsMode() ? 1 : 2)))
1288 return Error(IDLoc, "branch to misaligned address");
1290 case Mips::BEQZ16_MM:
1291 case Mips::BNEZ16_MM:
1292 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1293 Offset = Inst.getOperand(1);
1294 if (!Offset.isImm())
1295 break; // We'll deal with this situation later on when applying fixups.
1296 if (!isIntN(8, Offset.getImm()))
1297 return Error(IDLoc, "branch target out of range");
1298 if (OffsetToAlignment(Offset.getImm(), 2LL))
1299 return Error(IDLoc, "branch to misaligned address");
1304 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1305 // We still accept it but it is a normal nop.
1306 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1307 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1308 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1313 const unsigned Opcode = Inst.getOpcode();
1325 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1326 // The offset is handled above
1327 Opnd = Inst.getOperand(1);
1329 return Error(IDLoc, "expected immediate operand kind");
1330 Imm = Opnd.getImm();
1331 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1332 Opcode == Mips::BBIT1 ? 63 : 31))
1333 return Error(IDLoc, "immediate operand value out of range");
1335 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1337 Inst.getOperand(1).setImm(Imm - 32);
1345 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1347 Opnd = Inst.getOperand(3);
1349 return Error(IDLoc, "expected immediate operand kind");
1350 Imm = Opnd.getImm();
1351 if (Imm < 0 || Imm > 31)
1352 return Error(IDLoc, "immediate operand value out of range");
1354 Opnd = Inst.getOperand(2);
1356 return Error(IDLoc, "expected immediate operand kind");
1357 Imm = Opnd.getImm();
1358 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1359 Opcode == Mips::EXTS ? 63 : 31))
1360 return Error(IDLoc, "immediate operand value out of range");
1362 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1363 Inst.getOperand(2).setImm(Imm - 32);
1369 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1370 Opnd = Inst.getOperand(2);
1372 return Error(IDLoc, "expected immediate operand kind");
1373 Imm = Opnd.getImm();
1374 if (!isInt<10>(Imm))
1375 return Error(IDLoc, "immediate operand value out of range");
1380 // If this instruction has a delay slot and .set reorder is active,
1381 // emit a NOP after it.
1382 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1383 Instructions.push_back(Inst);
1384 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1388 if (MCID.mayLoad() || MCID.mayStore()) {
1389 // Check the offset of memory operand, if it is a symbol
1390 // reference or immediate we may have to expand instructions.
1391 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1392 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1393 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1394 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1395 MCOperand &Op = Inst.getOperand(i);
1397 int MemOffset = Op.getImm();
1398 if (MemOffset < -32768 || MemOffset > 32767) {
1399 // Offset can't exceed 16bit value.
1400 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1403 } else if (Op.isExpr()) {
1404 const MCExpr *Expr = Op.getExpr();
1405 if (Expr->getKind() == MCExpr::SymbolRef) {
1406 const MCSymbolRefExpr *SR =
1407 static_cast<const MCSymbolRefExpr *>(Expr);
1408 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1410 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1413 } else if (!isEvaluated(Expr)) {
1414 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1422 if (inMicroMipsMode()) {
1423 if (MCID.mayLoad()) {
1424 // Try to create 16-bit GP relative load instruction.
1425 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1426 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1427 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1428 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1429 MCOperand &Op = Inst.getOperand(i);
1431 int MemOffset = Op.getImm();
1432 MCOperand &DstReg = Inst.getOperand(0);
1433 MCOperand &BaseReg = Inst.getOperand(1);
1434 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1435 getContext().getRegisterInfo()->getRegClass(
1436 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1437 BaseReg.getReg() == Mips::GP) {
1439 TmpInst.setLoc(IDLoc);
1440 TmpInst.setOpcode(Mips::LWGP_MM);
1441 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1442 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1443 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1444 Instructions.push_back(TmpInst);
1452 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1457 switch (Inst.getOpcode()) {
1460 case Mips::ADDIUS5_MM:
1461 Opnd = Inst.getOperand(2);
1463 return Error(IDLoc, "expected immediate operand kind");
1464 Imm = Opnd.getImm();
1465 if (Imm < -8 || Imm > 7)
1466 return Error(IDLoc, "immediate operand value out of range");
1468 case Mips::ADDIUSP_MM:
1469 Opnd = Inst.getOperand(0);
1471 return Error(IDLoc, "expected immediate operand kind");
1472 Imm = Opnd.getImm();
1473 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1475 return Error(IDLoc, "immediate operand value out of range");
1477 case Mips::SLL16_MM:
1478 case Mips::SRL16_MM:
1479 Opnd = Inst.getOperand(2);
1481 return Error(IDLoc, "expected immediate operand kind");
1482 Imm = Opnd.getImm();
1483 if (Imm < 1 || Imm > 8)
1484 return Error(IDLoc, "immediate operand value out of range");
1487 Opnd = Inst.getOperand(1);
1489 return Error(IDLoc, "expected immediate operand kind");
1490 Imm = Opnd.getImm();
1491 if (Imm < -1 || Imm > 126)
1492 return Error(IDLoc, "immediate operand value out of range");
1494 case Mips::ADDIUR2_MM:
1495 Opnd = Inst.getOperand(2);
1497 return Error(IDLoc, "expected immediate operand kind");
1498 Imm = Opnd.getImm();
1499 if (!(Imm == 1 || Imm == -1 ||
1500 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1501 return Error(IDLoc, "immediate operand value out of range");
1503 case Mips::ADDIUR1SP_MM:
1504 Opnd = Inst.getOperand(1);
1506 return Error(IDLoc, "expected immediate operand kind");
1507 Imm = Opnd.getImm();
1508 if (OffsetToAlignment(Imm, 4LL))
1509 return Error(IDLoc, "misaligned immediate operand value");
1510 if (Imm < 0 || Imm > 255)
1511 return Error(IDLoc, "immediate operand value out of range");
1513 case Mips::ANDI16_MM:
1514 Opnd = Inst.getOperand(2);
1516 return Error(IDLoc, "expected immediate operand kind");
1517 Imm = Opnd.getImm();
1518 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1519 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1520 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1521 return Error(IDLoc, "immediate operand value out of range");
1523 case Mips::LBU16_MM:
1524 Opnd = Inst.getOperand(2);
1526 return Error(IDLoc, "expected immediate operand kind");
1527 Imm = Opnd.getImm();
1528 if (Imm < -1 || Imm > 14)
1529 return Error(IDLoc, "immediate operand value out of range");
1532 Opnd = Inst.getOperand(2);
1534 return Error(IDLoc, "expected immediate operand kind");
1535 Imm = Opnd.getImm();
1536 if (Imm < 0 || Imm > 15)
1537 return Error(IDLoc, "immediate operand value out of range");
1539 case Mips::LHU16_MM:
1541 Opnd = Inst.getOperand(2);
1543 return Error(IDLoc, "expected immediate operand kind");
1544 Imm = Opnd.getImm();
1545 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1546 return Error(IDLoc, "immediate operand value out of range");
1550 Opnd = Inst.getOperand(2);
1552 return Error(IDLoc, "expected immediate operand kind");
1553 Imm = Opnd.getImm();
1554 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1555 return Error(IDLoc, "immediate operand value out of range");
1559 Opnd = Inst.getOperand(2);
1561 return Error(IDLoc, "expected immediate operand kind");
1562 Imm = Opnd.getImm();
1563 if (!isUInt<5>(Imm))
1564 return Error(IDLoc, "immediate operand value out of range");
1566 case Mips::ADDIUPC_MM:
1567 MCOperand Opnd = Inst.getOperand(1);
1569 return Error(IDLoc, "expected immediate operand kind");
1570 int Imm = Opnd.getImm();
1571 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1572 return Error(IDLoc, "immediate operand value out of range");
1577 if (needsExpansion(Inst))
1578 return expandInstruction(Inst, IDLoc, Instructions);
1580 Instructions.push_back(Inst);
1585 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1587 switch (Inst.getOpcode()) {
1588 case Mips::LoadImm32:
1589 case Mips::LoadImm64:
1590 case Mips::LoadAddrImm32:
1591 case Mips::LoadAddrReg32:
1592 case Mips::B_MM_Pseudo:
1595 case Mips::JalOneReg:
1596 case Mips::JalTwoReg:
1603 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1604 SmallVectorImpl<MCInst> &Instructions) {
1605 switch (Inst.getOpcode()) {
1606 default: llvm_unreachable("unimplemented expansion");
1607 case Mips::LoadImm32:
1608 return expandLoadImm(Inst, IDLoc, Instructions);
1609 case Mips::LoadImm64:
1611 Error(IDLoc, "instruction requires a 64-bit architecture");
1614 return expandLoadImm(Inst, IDLoc, Instructions);
1615 case Mips::LoadAddrImm32:
1616 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1617 case Mips::LoadAddrReg32:
1618 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1619 case Mips::B_MM_Pseudo:
1620 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1623 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1624 case Mips::JalOneReg:
1625 case Mips::JalTwoReg:
1626 return expandJalWithRegs(Inst, IDLoc, Instructions);
1631 template <bool PerformShift>
1632 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1633 SmallVectorImpl<MCInst> &Instructions) {
1636 tmpInst.setOpcode(Mips::DSLL);
1637 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1638 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1639 tmpInst.addOperand(MCOperand::CreateImm(16));
1640 tmpInst.setLoc(IDLoc);
1641 Instructions.push_back(tmpInst);
1644 tmpInst.setOpcode(Mips::ORi);
1645 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1646 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1647 tmpInst.addOperand(Operand);
1648 tmpInst.setLoc(IDLoc);
1649 Instructions.push_back(tmpInst);
1652 template <int Shift, bool PerformShift>
1653 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1654 SmallVectorImpl<MCInst> &Instructions) {
1655 createShiftOr<PerformShift>(
1656 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1657 IDLoc, Instructions);
1661 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1662 SmallVectorImpl<MCInst> &Instructions) {
1663 // Create a JALR instruction which is going to replace the pseudo-JAL.
1665 JalrInst.setLoc(IDLoc);
1666 const MCOperand FirstRegOp = Inst.getOperand(0);
1667 const unsigned Opcode = Inst.getOpcode();
1669 if (Opcode == Mips::JalOneReg) {
1670 // jal $rs => jalr $rs
1671 if (inMicroMipsMode()) {
1672 JalrInst.setOpcode(Mips::JALR16_MM);
1673 JalrInst.addOperand(FirstRegOp);
1675 JalrInst.setOpcode(Mips::JALR);
1676 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1677 JalrInst.addOperand(FirstRegOp);
1679 } else if (Opcode == Mips::JalTwoReg) {
1680 // jal $rd, $rs => jalr $rd, $rs
1681 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1682 JalrInst.addOperand(FirstRegOp);
1683 const MCOperand SecondRegOp = Inst.getOperand(1);
1684 JalrInst.addOperand(SecondRegOp);
1686 Instructions.push_back(JalrInst);
1688 // If .set reorder is active, emit a NOP after it.
1689 if (AssemblerOptions.back()->isReorder()) {
1690 // This is a 32-bit NOP because these 2 pseudo-instructions
1691 // do not have a short delay slot.
1693 NopInst.setOpcode(Mips::SLL);
1694 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1695 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1696 NopInst.addOperand(MCOperand::CreateImm(0));
1697 Instructions.push_back(NopInst);
1703 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1704 SmallVectorImpl<MCInst> &Instructions) {
1706 const MCOperand &ImmOp = Inst.getOperand(1);
1707 assert(ImmOp.isImm() && "expected immediate operand kind");
1708 const MCOperand &RegOp = Inst.getOperand(0);
1709 assert(RegOp.isReg() && "expected register operand kind");
1711 int64_t ImmValue = ImmOp.getImm();
1712 tmpInst.setLoc(IDLoc);
1713 // FIXME: gas has a special case for values that are 000...1111, which
1714 // becomes a li -1 and then a dsrl
1715 if (0 <= ImmValue && ImmValue <= 65535) {
1716 // For 0 <= j <= 65535.
1717 // li d,j => ori d,$zero,j
1718 tmpInst.setOpcode(Mips::ORi);
1719 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1720 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1721 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1722 Instructions.push_back(tmpInst);
1723 } else if (ImmValue < 0 && ImmValue >= -32768) {
1724 // For -32768 <= j < 0.
1725 // li d,j => addiu d,$zero,j
1726 tmpInst.setOpcode(Mips::ADDiu);
1727 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1728 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1729 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1730 Instructions.push_back(tmpInst);
1731 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1732 // For any value of j that is representable as a 32-bit integer, create
1734 // li d,j => lui d,hi16(j)
1736 tmpInst.setOpcode(Mips::LUi);
1737 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1738 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1739 Instructions.push_back(tmpInst);
1740 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1741 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1743 Error(IDLoc, "instruction requires a 64-bit architecture");
1747 // <------- lo32 ------>
1748 // <------- hi32 ------>
1749 // <- hi16 -> <- lo16 ->
1750 // _________________________________
1752 // | 16-bytes | 16-bytes | 16-bytes |
1753 // |__________|__________|__________|
1755 // For any value of j that is representable as a 48-bit integer, create
1757 // li d,j => lui d,hi16(j)
1758 // ori d,d,hi16(lo32(j))
1760 // ori d,d,lo16(lo32(j))
1761 tmpInst.setOpcode(Mips::LUi);
1762 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1764 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1765 Instructions.push_back(tmpInst);
1766 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1767 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1770 Error(IDLoc, "instruction requires a 64-bit architecture");
1774 // <------- hi32 ------> <------- lo32 ------>
1775 // <- hi16 -> <- lo16 ->
1776 // ___________________________________________
1778 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1779 // |__________|__________|__________|__________|
1781 // For any value of j that isn't representable as a 48-bit integer.
1782 // li d,j => lui d,hi16(j)
1783 // ori d,d,lo16(hi32(j))
1785 // ori d,d,hi16(lo32(j))
1787 // ori d,d,lo16(lo32(j))
1788 tmpInst.setOpcode(Mips::LUi);
1789 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1791 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1792 Instructions.push_back(tmpInst);
1793 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1794 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1795 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1801 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1802 SmallVectorImpl<MCInst> &Instructions) {
1804 const MCOperand &ImmOp = Inst.getOperand(2);
1805 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1806 "expected immediate operand kind");
1807 if (!ImmOp.isImm()) {
1808 expandLoadAddressSym(Inst, IDLoc, Instructions);
1811 const MCOperand &SrcRegOp = Inst.getOperand(1);
1812 assert(SrcRegOp.isReg() && "expected register operand kind");
1813 const MCOperand &DstRegOp = Inst.getOperand(0);
1814 assert(DstRegOp.isReg() && "expected register operand kind");
1815 int ImmValue = ImmOp.getImm();
1816 if (-32768 <= ImmValue && ImmValue <= 65535) {
1817 // For -32768 <= j <= 65535.
1818 // la d,j(s) => addiu d,s,j
1819 tmpInst.setOpcode(Mips::ADDiu);
1820 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1821 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1822 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1823 Instructions.push_back(tmpInst);
1825 // For any other value of j that is representable as a 32-bit integer.
1826 // la d,j(s) => lui d,hi16(j)
1829 tmpInst.setOpcode(Mips::LUi);
1830 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1831 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1832 Instructions.push_back(tmpInst);
1834 tmpInst.setOpcode(Mips::ORi);
1835 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1836 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1837 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1838 Instructions.push_back(tmpInst);
1840 tmpInst.setOpcode(Mips::ADDu);
1841 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1842 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1843 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1844 Instructions.push_back(tmpInst);
1850 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1851 SmallVectorImpl<MCInst> &Instructions) {
1853 const MCOperand &ImmOp = Inst.getOperand(1);
1854 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1855 "expected immediate operand kind");
1856 if (!ImmOp.isImm()) {
1857 expandLoadAddressSym(Inst, IDLoc, Instructions);
1860 const MCOperand &RegOp = Inst.getOperand(0);
1861 assert(RegOp.isReg() && "expected register operand kind");
1862 int ImmValue = ImmOp.getImm();
1863 if (-32768 <= ImmValue && ImmValue <= 65535) {
1864 // For -32768 <= j <= 65535.
1865 // la d,j => addiu d,$zero,j
1866 tmpInst.setOpcode(Mips::ADDiu);
1867 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1868 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1869 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1870 Instructions.push_back(tmpInst);
1872 // For any other value of j that is representable as a 32-bit integer.
1873 // la d,j => lui d,hi16(j)
1875 tmpInst.setOpcode(Mips::LUi);
1876 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1877 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1878 Instructions.push_back(tmpInst);
1880 tmpInst.setOpcode(Mips::ORi);
1881 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1882 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1883 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1884 Instructions.push_back(tmpInst);
1890 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1891 SmallVectorImpl<MCInst> &Instructions) {
1892 // FIXME: If we do have a valid at register to use, we should generate a
1893 // slightly shorter sequence here.
1895 int ExprOperandNo = 1;
1896 // Sometimes the assembly parser will get the immediate expression as
1897 // a $zero + an immediate.
1898 if (Inst.getNumOperands() == 3) {
1899 assert(Inst.getOperand(1).getReg() ==
1900 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1903 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1904 assert(SymOp.isExpr() && "expected symbol operand kind");
1905 const MCOperand &RegOp = Inst.getOperand(0);
1906 unsigned RegNo = RegOp.getReg();
1907 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1908 const MCSymbolRefExpr *HiExpr =
1909 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1910 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1911 const MCSymbolRefExpr *LoExpr =
1912 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1913 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1915 // If it's a 64-bit architecture, expand to:
1916 // la d,sym => lui d,highest(sym)
1917 // ori d,d,higher(sym)
1919 // ori d,d,hi16(sym)
1921 // ori d,d,lo16(sym)
1922 const MCSymbolRefExpr *HighestExpr =
1923 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1924 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1925 const MCSymbolRefExpr *HigherExpr =
1926 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1927 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1929 tmpInst.setOpcode(Mips::LUi);
1930 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1931 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1932 Instructions.push_back(tmpInst);
1934 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1936 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1938 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1941 // Otherwise, expand to:
1942 // la d,sym => lui d,hi16(sym)
1943 // ori d,d,lo16(sym)
1944 tmpInst.setOpcode(Mips::LUi);
1945 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1946 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1947 Instructions.push_back(tmpInst);
1949 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1954 bool MipsAsmParser::expandUncondBranchMMPseudo(
1955 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1956 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1957 "unexpected number of operands");
1959 MCOperand Offset = Inst.getOperand(0);
1960 if (Offset.isExpr()) {
1962 Inst.setOpcode(Mips::BEQ_MM);
1963 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1964 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1965 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1967 assert(Offset.isImm() && "expected immediate operand kind");
1968 if (isIntN(11, Offset.getImm())) {
1969 // If offset fits into 11 bits then this instruction becomes microMIPS
1970 // 16-bit unconditional branch instruction.
1971 Inst.setOpcode(Mips::B16_MM);
1973 if (!isIntN(17, Offset.getImm()))
1974 Error(IDLoc, "branch target out of range");
1975 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1976 Error(IDLoc, "branch to misaligned address");
1978 Inst.setOpcode(Mips::BEQ_MM);
1979 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1980 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1981 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1984 Instructions.push_back(Inst);
1986 // If .set reorder is active, emit a NOP after the branch instruction.
1987 if (AssemblerOptions.back()->isReorder())
1988 createNop(true, IDLoc, Instructions);
1993 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1994 SmallVectorImpl<MCInst> &Instructions,
1995 bool isLoad, bool isImmOpnd) {
1996 const MCSymbolRefExpr *SR;
1998 unsigned ImmOffset, HiOffset, LoOffset;
1999 const MCExpr *ExprOffset;
2001 // 1st operand is either the source or destination register.
2002 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2003 unsigned RegOpNum = Inst.getOperand(0).getReg();
2004 // 2nd operand is the base register.
2005 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2006 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2007 // 3rd operand is either an immediate or expression.
2009 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2010 ImmOffset = Inst.getOperand(2).getImm();
2011 LoOffset = ImmOffset & 0x0000ffff;
2012 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2013 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2014 if (LoOffset & 0x8000)
2017 ExprOffset = Inst.getOperand(2).getExpr();
2018 // All instructions will have the same location.
2019 TempInst.setLoc(IDLoc);
2020 // These are some of the types of expansions we perform here:
2021 // 1) lw $8, sym => lui $8, %hi(sym)
2022 // lw $8, %lo(sym)($8)
2023 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2025 // lw $8, %lo(offset)($9)
2026 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2028 // lw $8, %lo(offset)($at)
2029 // 4) sw $8, sym => lui $at, %hi(sym)
2030 // sw $8, %lo(sym)($at)
2031 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2033 // sw $8, %lo(offset)($at)
2034 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2035 // ldc1 $f0, %lo(sym)($at)
2037 // For load instructions we can use the destination register as a temporary
2038 // if base and dst are different (examples 1 and 2) and if the base register
2039 // is general purpose otherwise we must use $at (example 6) and error if it's
2040 // not available. For stores we must use $at (examples 4 and 5) because we
2041 // must not clobber the source register setting up the offset.
2042 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2043 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2044 unsigned RegClassIDOp0 =
2045 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2046 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2047 (RegClassIDOp0 == Mips::GPR64RegClassID);
2048 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2049 TmpRegNum = RegOpNum;
2051 int AT = getATReg(IDLoc);
2052 // At this point we need AT to perform the expansions and we exit if it is
2057 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
2060 TempInst.setOpcode(Mips::LUi);
2061 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2063 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2065 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2066 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2067 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2068 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2070 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2072 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2073 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2076 // Add the instruction to the list.
2077 Instructions.push_back(TempInst);
2078 // Prepare TempInst for next instruction.
2080 // Add temp register to base.
2081 TempInst.setOpcode(Mips::ADDu);
2082 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2083 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2084 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2085 Instructions.push_back(TempInst);
2087 // And finally, create original instruction with low part
2088 // of offset and new base.
2089 TempInst.setOpcode(Inst.getOpcode());
2090 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2091 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2093 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2095 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2096 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2097 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2099 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2101 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2102 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2105 Instructions.push_back(TempInst);
2110 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2111 SmallVectorImpl<MCInst> &Instructions) {
2112 unsigned OpNum = Inst.getNumOperands();
2113 unsigned Opcode = Inst.getOpcode();
2114 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2116 assert (Inst.getOperand(OpNum - 1).isImm() &&
2117 Inst.getOperand(OpNum - 2).isReg() &&
2118 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2120 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2121 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2122 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2123 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2124 // It can be implemented as SWM16 or LWM16 instruction.
2125 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2127 Inst.setOpcode(NewOpcode);
2128 Instructions.push_back(Inst);
2132 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2133 SmallVectorImpl<MCInst> &Instructions) {
2135 if (hasShortDelaySlot) {
2136 NopInst.setOpcode(Mips::MOVE16_MM);
2137 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2138 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2140 NopInst.setOpcode(Mips::SLL);
2141 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2142 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2143 NopInst.addOperand(MCOperand::CreateImm(0));
2145 Instructions.push_back(NopInst);
2148 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2149 // As described by the Mips32r2 spec, the registers Rd and Rs for
2150 // jalr.hb must be different.
2151 unsigned Opcode = Inst.getOpcode();
2153 if (Opcode == Mips::JALR_HB &&
2154 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2155 return Match_RequiresDifferentSrcAndDst;
2157 return Match_Success;
2160 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2161 OperandVector &Operands,
2163 uint64_t &ErrorInfo,
2164 bool MatchingInlineAsm) {
2167 SmallVector<MCInst, 8> Instructions;
2168 unsigned MatchResult =
2169 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2171 switch (MatchResult) {
2172 case Match_Success: {
2173 if (processInstruction(Inst, IDLoc, Instructions))
2175 for (unsigned i = 0; i < Instructions.size(); i++)
2176 Out.EmitInstruction(Instructions[i], STI);
2179 case Match_MissingFeature:
2180 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2182 case Match_InvalidOperand: {
2183 SMLoc ErrorLoc = IDLoc;
2184 if (ErrorInfo != ~0ULL) {
2185 if (ErrorInfo >= Operands.size())
2186 return Error(IDLoc, "too few operands for instruction");
2188 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2189 if (ErrorLoc == SMLoc())
2193 return Error(ErrorLoc, "invalid operand for instruction");
2195 case Match_MnemonicFail:
2196 return Error(IDLoc, "invalid instruction");
2197 case Match_RequiresDifferentSrcAndDst:
2198 return Error(IDLoc, "source and destination must be different");
2201 llvm_unreachable("Implement any new match types added!");
2204 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
2205 if ((RegIndex != 0) &&
2206 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
2208 Warning(Loc, "used $at without \".set noat\"");
2210 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
2211 Twine(RegIndex) + "\"");
2216 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2217 SMRange Range, bool ShowColors) {
2218 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2219 Range, SMFixIt(Range, FixMsg),
2223 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2226 CC = StringSwitch<unsigned>(Name)
2262 if (!(isABI_N32() || isABI_N64()))
2265 if (12 <= CC && CC <= 15) {
2266 // Name is one of t4-t7
2267 AsmToken RegTok = getLexer().peekTok();
2268 SMRange RegRange = RegTok.getLocRange();
2270 StringRef FixedName = StringSwitch<StringRef>(Name)
2276 assert(FixedName != "" && "Register name is not one of t4-t7.");
2278 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2279 "Did you mean $" + FixedName + "?", RegRange);
2282 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2283 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2284 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2285 if (8 <= CC && CC <= 11)
2289 CC = StringSwitch<unsigned>(Name)
2301 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2304 CC = StringSwitch<unsigned>(Name)
2305 .Case("hwr_cpunum", 0)
2306 .Case("hwr_synci_step", 1)
2308 .Case("hwr_ccres", 3)
2309 .Case("hwr_ulr", 29)
2315 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2317 if (Name[0] == 'f') {
2318 StringRef NumString = Name.substr(1);
2320 if (NumString.getAsInteger(10, IntVal))
2321 return -1; // This is not an integer.
2322 if (IntVal > 31) // Maximum index for fpu register.
2329 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2331 if (Name.startswith("fcc")) {
2332 StringRef NumString = Name.substr(3);
2334 if (NumString.getAsInteger(10, IntVal))
2335 return -1; // This is not an integer.
2336 if (IntVal > 7) // There are only 8 fcc registers.
2343 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2345 if (Name.startswith("ac")) {
2346 StringRef NumString = Name.substr(2);
2348 if (NumString.getAsInteger(10, IntVal))
2349 return -1; // This is not an integer.
2350 if (IntVal > 3) // There are only 3 acc registers.
2357 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2360 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2369 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2372 CC = StringSwitch<unsigned>(Name)
2375 .Case("msaaccess", 2)
2377 .Case("msamodify", 4)
2378 .Case("msarequest", 5)
2380 .Case("msaunmap", 7)
2386 int MipsAsmParser::getATReg(SMLoc Loc) {
2387 int AT = AssemblerOptions.back()->getATRegNum();
2389 reportParseError(Loc,
2390 "pseudo-instruction requires $at, which is not available");
2394 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2395 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2398 unsigned MipsAsmParser::getGPR(int RegNo) {
2399 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2403 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2405 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2408 return getReg(RegClass, RegNum);
2411 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2412 MCAsmParser &Parser = getParser();
2413 DEBUG(dbgs() << "parseOperand\n");
2415 // Check if the current operand has a custom associated parser, if so, try to
2416 // custom parse the operand, or fallback to the general approach.
2417 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2418 if (ResTy == MatchOperand_Success)
2420 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2421 // there was a match, but an error occurred, in which case, just return that
2422 // the operand parsing failed.
2423 if (ResTy == MatchOperand_ParseFail)
2426 DEBUG(dbgs() << ".. Generic Parser\n");
2428 switch (getLexer().getKind()) {
2430 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2432 case AsmToken::Dollar: {
2433 // Parse the register.
2434 SMLoc S = Parser.getTok().getLoc();
2436 // Almost all registers have been parsed by custom parsers. There is only
2437 // one exception to this. $zero (and it's alias $0) will reach this point
2438 // for div, divu, and similar instructions because it is not an operand
2439 // to the instruction definition but an explicit register. Special case
2440 // this situation for now.
2441 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2444 // Maybe it is a symbol reference.
2445 StringRef Identifier;
2446 if (Parser.parseIdentifier(Identifier))
2449 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2450 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2451 // Otherwise create a symbol reference.
2453 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2455 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2458 // Else drop to expression parsing.
2459 case AsmToken::LParen:
2460 case AsmToken::Minus:
2461 case AsmToken::Plus:
2462 case AsmToken::Integer:
2463 case AsmToken::Tilde:
2464 case AsmToken::String: {
2465 DEBUG(dbgs() << ".. generic integer\n");
2466 OperandMatchResultTy ResTy = parseImm(Operands);
2467 return ResTy != MatchOperand_Success;
2469 case AsmToken::Percent: {
2470 // It is a symbol reference or constant expression.
2471 const MCExpr *IdVal;
2472 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2473 if (parseRelocOperand(IdVal))
2476 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2478 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2480 } // case AsmToken::Percent
2481 } // switch(getLexer().getKind())
2485 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2486 StringRef RelocStr) {
2488 // Check the type of the expression.
2489 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2490 // It's a constant, evaluate reloc value.
2492 switch (getVariantKind(RelocStr)) {
2493 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2494 // Get the 1st 16-bits.
2495 Val = MCE->getValue() & 0xffff;
2497 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2498 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2499 // 16 bits being negative.
2500 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2502 case MCSymbolRefExpr::VK_Mips_HIGHER:
2503 // Get the 3rd 16-bits.
2504 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2506 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2507 // Get the 4th 16-bits.
2508 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2511 report_fatal_error("unsupported reloc value");
2513 return MCConstantExpr::Create(Val, getContext());
2516 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2517 // It's a symbol, create a symbolic expression from the symbol.
2518 StringRef Symbol = MSRE->getSymbol().getName();
2519 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2520 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2524 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2525 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2527 // Try to create target expression.
2528 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2529 return MipsMCExpr::Create(VK, Expr, getContext());
2531 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2532 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2533 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2537 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2538 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2539 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2542 // Just return the original expression.
2546 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2548 switch (Expr->getKind()) {
2549 case MCExpr::Constant:
2551 case MCExpr::SymbolRef:
2552 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2553 case MCExpr::Binary:
2554 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2555 if (!isEvaluated(BE->getLHS()))
2557 return isEvaluated(BE->getRHS());
2560 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2561 case MCExpr::Target:
2567 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2568 MCAsmParser &Parser = getParser();
2569 Parser.Lex(); // Eat the % token.
2570 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2571 if (Tok.isNot(AsmToken::Identifier))
2574 std::string Str = Tok.getIdentifier();
2576 Parser.Lex(); // Eat the identifier.
2577 // Now make an expression from the rest of the operand.
2578 const MCExpr *IdVal;
2581 if (getLexer().getKind() == AsmToken::LParen) {
2583 Parser.Lex(); // Eat the '(' token.
2584 if (getLexer().getKind() == AsmToken::Percent) {
2585 Parser.Lex(); // Eat the % token.
2586 const AsmToken &nextTok = Parser.getTok();
2587 if (nextTok.isNot(AsmToken::Identifier))
2590 Str += nextTok.getIdentifier();
2591 Parser.Lex(); // Eat the identifier.
2592 if (getLexer().getKind() != AsmToken::LParen)
2597 if (getParser().parseParenExpression(IdVal, EndLoc))
2600 while (getLexer().getKind() == AsmToken::RParen)
2601 Parser.Lex(); // Eat the ')' token.
2604 return true; // Parenthesis must follow the relocation operand.
2606 Res = evaluateRelocExpr(IdVal, Str);
2610 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2612 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2613 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2614 if (ResTy == MatchOperand_Success) {
2615 assert(Operands.size() == 1);
2616 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2617 StartLoc = Operand.getStartLoc();
2618 EndLoc = Operand.getEndLoc();
2620 // AFAIK, we only support numeric registers and named GPR's in CFI
2622 // Don't worry about eating tokens before failing. Using an unrecognised
2623 // register is a parse error.
2624 if (Operand.isGPRAsmReg()) {
2625 // Resolve to GPR32 or GPR64 appropriately.
2626 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2629 return (RegNo == (unsigned)-1);
2632 assert(Operands.size() == 0);
2633 return (RegNo == (unsigned)-1);
2636 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2637 MCAsmParser &Parser = getParser();
2641 while (getLexer().getKind() == AsmToken::LParen)
2644 switch (getLexer().getKind()) {
2647 case AsmToken::Identifier:
2648 case AsmToken::LParen:
2649 case AsmToken::Integer:
2650 case AsmToken::Minus:
2651 case AsmToken::Plus:
2653 Result = getParser().parseParenExpression(Res, S);
2655 Result = (getParser().parseExpression(Res));
2656 while (getLexer().getKind() == AsmToken::RParen)
2659 case AsmToken::Percent:
2660 Result = parseRelocOperand(Res);
2665 MipsAsmParser::OperandMatchResultTy
2666 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2667 MCAsmParser &Parser = getParser();
2668 DEBUG(dbgs() << "parseMemOperand\n");
2669 const MCExpr *IdVal = nullptr;
2671 bool isParenExpr = false;
2672 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2673 // First operand is the offset.
2674 S = Parser.getTok().getLoc();
2676 if (getLexer().getKind() == AsmToken::LParen) {
2681 if (getLexer().getKind() != AsmToken::Dollar) {
2682 if (parseMemOffset(IdVal, isParenExpr))
2683 return MatchOperand_ParseFail;
2685 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2686 if (Tok.isNot(AsmToken::LParen)) {
2687 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2688 if (Mnemonic.getToken() == "la") {
2690 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2691 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2692 return MatchOperand_Success;
2694 if (Tok.is(AsmToken::EndOfStatement)) {
2696 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2698 // Zero register assumed, add a memory operand with ZERO as its base.
2699 // "Base" will be managed by k_Memory.
2700 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2703 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2704 return MatchOperand_Success;
2706 Error(Parser.getTok().getLoc(), "'(' expected");
2707 return MatchOperand_ParseFail;
2710 Parser.Lex(); // Eat the '(' token.
2713 Res = parseAnyRegister(Operands);
2714 if (Res != MatchOperand_Success)
2717 if (Parser.getTok().isNot(AsmToken::RParen)) {
2718 Error(Parser.getTok().getLoc(), "')' expected");
2719 return MatchOperand_ParseFail;
2722 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2724 Parser.Lex(); // Eat the ')' token.
2727 IdVal = MCConstantExpr::Create(0, getContext());
2729 // Replace the register operand with the memory operand.
2730 std::unique_ptr<MipsOperand> op(
2731 static_cast<MipsOperand *>(Operands.back().release()));
2732 // Remove the register from the operands.
2733 // "op" will be managed by k_Memory.
2734 Operands.pop_back();
2735 // Add the memory operand.
2736 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2738 if (IdVal->EvaluateAsAbsolute(Imm))
2739 IdVal = MCConstantExpr::Create(Imm, getContext());
2740 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2741 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2745 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2746 return MatchOperand_Success;
2749 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2750 MCAsmParser &Parser = getParser();
2751 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2753 SMLoc S = Parser.getTok().getLoc();
2755 if (Sym->isVariable())
2756 Expr = Sym->getVariableValue();
2759 if (Expr->getKind() == MCExpr::SymbolRef) {
2760 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2761 StringRef DefSymbol = Ref->getSymbol().getName();
2762 if (DefSymbol.startswith("$")) {
2763 OperandMatchResultTy ResTy =
2764 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2765 if (ResTy == MatchOperand_Success) {
2768 } else if (ResTy == MatchOperand_ParseFail)
2769 llvm_unreachable("Should never ParseFail");
2772 } else if (Expr->getKind() == MCExpr::Constant) {
2774 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2776 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2783 MipsAsmParser::OperandMatchResultTy
2784 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2785 StringRef Identifier,
2787 int Index = matchCPURegisterName(Identifier);
2789 Operands.push_back(MipsOperand::createGPRReg(
2790 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2791 return MatchOperand_Success;
2794 Index = matchHWRegsRegisterName(Identifier);
2796 Operands.push_back(MipsOperand::createHWRegsReg(
2797 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2798 return MatchOperand_Success;
2801 Index = matchFPURegisterName(Identifier);
2803 Operands.push_back(MipsOperand::createFGRReg(
2804 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2805 return MatchOperand_Success;
2808 Index = matchFCCRegisterName(Identifier);
2810 Operands.push_back(MipsOperand::createFCCReg(
2811 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2812 return MatchOperand_Success;
2815 Index = matchACRegisterName(Identifier);
2817 Operands.push_back(MipsOperand::createACCReg(
2818 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2819 return MatchOperand_Success;
2822 Index = matchMSA128RegisterName(Identifier);
2824 Operands.push_back(MipsOperand::createMSA128Reg(
2825 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2826 return MatchOperand_Success;
2829 Index = matchMSA128CtrlRegisterName(Identifier);
2831 Operands.push_back(MipsOperand::createMSACtrlReg(
2832 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2833 return MatchOperand_Success;
2836 return MatchOperand_NoMatch;
2839 MipsAsmParser::OperandMatchResultTy
2840 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2841 MCAsmParser &Parser = getParser();
2842 auto Token = Parser.getLexer().peekTok(false);
2844 if (Token.is(AsmToken::Identifier)) {
2845 DEBUG(dbgs() << ".. identifier\n");
2846 StringRef Identifier = Token.getIdentifier();
2847 OperandMatchResultTy ResTy =
2848 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2850 } else if (Token.is(AsmToken::Integer)) {
2851 DEBUG(dbgs() << ".. integer\n");
2852 Operands.push_back(MipsOperand::createNumericReg(
2853 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2855 return MatchOperand_Success;
2858 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2860 return MatchOperand_NoMatch;
2863 MipsAsmParser::OperandMatchResultTy
2864 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2865 MCAsmParser &Parser = getParser();
2866 DEBUG(dbgs() << "parseAnyRegister\n");
2868 auto Token = Parser.getTok();
2870 SMLoc S = Token.getLoc();
2872 if (Token.isNot(AsmToken::Dollar)) {
2873 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2874 if (Token.is(AsmToken::Identifier)) {
2875 if (searchSymbolAlias(Operands))
2876 return MatchOperand_Success;
2878 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2879 return MatchOperand_NoMatch;
2881 DEBUG(dbgs() << ".. $\n");
2883 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2884 if (ResTy == MatchOperand_Success) {
2886 Parser.Lex(); // identifier
2891 MipsAsmParser::OperandMatchResultTy
2892 MipsAsmParser::parseImm(OperandVector &Operands) {
2893 MCAsmParser &Parser = getParser();
2894 switch (getLexer().getKind()) {
2896 return MatchOperand_NoMatch;
2897 case AsmToken::LParen:
2898 case AsmToken::Minus:
2899 case AsmToken::Plus:
2900 case AsmToken::Integer:
2901 case AsmToken::Tilde:
2902 case AsmToken::String:
2906 const MCExpr *IdVal;
2907 SMLoc S = Parser.getTok().getLoc();
2908 if (getParser().parseExpression(IdVal))
2909 return MatchOperand_ParseFail;
2911 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2912 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2913 return MatchOperand_Success;
2916 MipsAsmParser::OperandMatchResultTy
2917 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2918 MCAsmParser &Parser = getParser();
2919 DEBUG(dbgs() << "parseJumpTarget\n");
2921 SMLoc S = getLexer().getLoc();
2923 // Integers and expressions are acceptable
2924 OperandMatchResultTy ResTy = parseImm(Operands);
2925 if (ResTy != MatchOperand_NoMatch)
2928 // Registers are a valid target and have priority over symbols.
2929 ResTy = parseAnyRegister(Operands);
2930 if (ResTy != MatchOperand_NoMatch)
2933 const MCExpr *Expr = nullptr;
2934 if (Parser.parseExpression(Expr)) {
2935 // We have no way of knowing if a symbol was consumed so we must ParseFail
2936 return MatchOperand_ParseFail;
2939 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2940 return MatchOperand_Success;
2943 MipsAsmParser::OperandMatchResultTy
2944 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2945 MCAsmParser &Parser = getParser();
2946 const MCExpr *IdVal;
2947 // If the first token is '$' we may have register operand.
2948 if (Parser.getTok().is(AsmToken::Dollar))
2949 return MatchOperand_NoMatch;
2950 SMLoc S = Parser.getTok().getLoc();
2951 if (getParser().parseExpression(IdVal))
2952 return MatchOperand_ParseFail;
2953 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2954 assert(MCE && "Unexpected MCExpr type.");
2955 int64_t Val = MCE->getValue();
2956 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2957 Operands.push_back(MipsOperand::CreateImm(
2958 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2959 return MatchOperand_Success;
2962 MipsAsmParser::OperandMatchResultTy
2963 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2964 MCAsmParser &Parser = getParser();
2965 switch (getLexer().getKind()) {
2967 return MatchOperand_NoMatch;
2968 case AsmToken::LParen:
2969 case AsmToken::Plus:
2970 case AsmToken::Minus:
2971 case AsmToken::Integer:
2976 SMLoc S = Parser.getTok().getLoc();
2978 if (getParser().parseExpression(Expr))
2979 return MatchOperand_ParseFail;
2982 if (!Expr->EvaluateAsAbsolute(Val)) {
2983 Error(S, "expected immediate value");
2984 return MatchOperand_ParseFail;
2987 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2988 // and because the CPU always adds one to the immediate field, the allowed
2989 // range becomes 1..4. We'll only check the range here and will deal
2990 // with the addition/subtraction when actually decoding/encoding
2992 if (Val < 1 || Val > 4) {
2993 Error(S, "immediate not in range (1..4)");
2994 return MatchOperand_ParseFail;
2998 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2999 return MatchOperand_Success;
3002 MipsAsmParser::OperandMatchResultTy
3003 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3004 MCAsmParser &Parser = getParser();
3005 SmallVector<unsigned, 10> Regs;
3007 unsigned PrevReg = Mips::NoRegister;
3008 bool RegRange = false;
3009 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3011 if (Parser.getTok().isNot(AsmToken::Dollar))
3012 return MatchOperand_ParseFail;
3014 SMLoc S = Parser.getTok().getLoc();
3015 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3016 SMLoc E = getLexer().getLoc();
3017 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3018 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3020 // Remove last register operand because registers from register range
3021 // should be inserted first.
3022 if (RegNo == Mips::RA) {
3023 Regs.push_back(RegNo);
3025 unsigned TmpReg = PrevReg + 1;
3026 while (TmpReg <= RegNo) {
3027 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3028 Error(E, "invalid register operand");
3029 return MatchOperand_ParseFail;
3033 Regs.push_back(TmpReg++);
3039 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3040 (RegNo != Mips::RA)) {
3041 Error(E, "$16 or $31 expected");
3042 return MatchOperand_ParseFail;
3043 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3044 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3045 Error(E, "invalid register operand");
3046 return MatchOperand_ParseFail;
3047 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3048 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3049 Error(E, "consecutive register numbers expected");
3050 return MatchOperand_ParseFail;
3053 Regs.push_back(RegNo);
3056 if (Parser.getTok().is(AsmToken::Minus))
3059 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3060 !Parser.getTok().isNot(AsmToken::Comma)) {
3061 Error(E, "',' or '-' expected");
3062 return MatchOperand_ParseFail;
3065 Lex(); // Consume comma or minus
3066 if (Parser.getTok().isNot(AsmToken::Dollar))
3072 SMLoc E = Parser.getTok().getLoc();
3073 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3074 parseMemOperand(Operands);
3075 return MatchOperand_Success;
3078 MipsAsmParser::OperandMatchResultTy
3079 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3080 MCAsmParser &Parser = getParser();
3082 SMLoc S = Parser.getTok().getLoc();
3083 if (parseAnyRegister(Operands) != MatchOperand_Success)
3084 return MatchOperand_ParseFail;
3086 SMLoc E = Parser.getTok().getLoc();
3087 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3088 unsigned Reg = Op.getGPR32Reg();
3089 Operands.pop_back();
3090 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3091 return MatchOperand_Success;
3094 MipsAsmParser::OperandMatchResultTy
3095 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3096 MCAsmParser &Parser = getParser();
3097 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3098 SmallVector<unsigned, 10> Regs;
3100 if (Parser.getTok().isNot(AsmToken::Dollar))
3101 return MatchOperand_ParseFail;
3103 SMLoc S = Parser.getTok().getLoc();
3105 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3106 return MatchOperand_ParseFail;
3108 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3109 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3110 Regs.push_back(RegNo);
3112 SMLoc E = Parser.getTok().getLoc();
3113 if (Parser.getTok().isNot(AsmToken::Comma)) {
3114 Error(E, "',' expected");
3115 return MatchOperand_ParseFail;
3121 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3122 return MatchOperand_ParseFail;
3124 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3125 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3126 Regs.push_back(RegNo);
3128 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3130 return MatchOperand_Success;
3133 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3135 MCSymbolRefExpr::VariantKind VK =
3136 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3137 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3138 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3139 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3140 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3141 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3142 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3143 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3144 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3145 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3146 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3147 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3148 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3149 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3150 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3151 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3152 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3153 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3154 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3155 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3156 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3157 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3158 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3159 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3160 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3161 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3162 .Default(MCSymbolRefExpr::VK_None);
3164 assert(VK != MCSymbolRefExpr::VK_None);
3169 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3171 /// ::= '(', register, ')'
3172 /// handle it before we iterate so we don't get tripped up by the lack of
3174 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3175 MCAsmParser &Parser = getParser();
3176 if (getLexer().is(AsmToken::LParen)) {
3178 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3180 if (parseOperand(Operands, Name)) {
3181 SMLoc Loc = getLexer().getLoc();
3182 Parser.eatToEndOfStatement();
3183 return Error(Loc, "unexpected token in argument list");
3185 if (Parser.getTok().isNot(AsmToken::RParen)) {
3186 SMLoc Loc = getLexer().getLoc();
3187 Parser.eatToEndOfStatement();
3188 return Error(Loc, "unexpected token, expected ')'");
3191 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3197 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3198 /// either one of these.
3199 /// ::= '[', register, ']'
3200 /// ::= '[', integer, ']'
3201 /// handle it before we iterate so we don't get tripped up by the lack of
3203 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3204 OperandVector &Operands) {
3205 MCAsmParser &Parser = getParser();
3206 if (getLexer().is(AsmToken::LBrac)) {
3208 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3210 if (parseOperand(Operands, Name)) {
3211 SMLoc Loc = getLexer().getLoc();
3212 Parser.eatToEndOfStatement();
3213 return Error(Loc, "unexpected token in argument list");
3215 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3216 SMLoc Loc = getLexer().getLoc();
3217 Parser.eatToEndOfStatement();
3218 return Error(Loc, "unexpected token, expected ']'");
3221 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3227 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3228 SMLoc NameLoc, OperandVector &Operands) {
3229 MCAsmParser &Parser = getParser();
3230 DEBUG(dbgs() << "ParseInstruction\n");
3232 // We have reached first instruction, module directive are now forbidden.
3233 getTargetStreamer().forbidModuleDirective();
3235 // Check if we have valid mnemonic
3236 if (!mnemonicIsValid(Name, 0)) {
3237 Parser.eatToEndOfStatement();
3238 return Error(NameLoc, "unknown instruction");
3240 // First operand in MCInst is instruction mnemonic.
3241 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3243 // Read the remaining operands.
3244 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3245 // Read the first operand.
3246 if (parseOperand(Operands, Name)) {
3247 SMLoc Loc = getLexer().getLoc();
3248 Parser.eatToEndOfStatement();
3249 return Error(Loc, "unexpected token in argument list");
3251 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3253 // AFAIK, parenthesis suffixes are never on the first operand
3255 while (getLexer().is(AsmToken::Comma)) {
3256 Parser.Lex(); // Eat the comma.
3257 // Parse and remember the operand.
3258 if (parseOperand(Operands, Name)) {
3259 SMLoc Loc = getLexer().getLoc();
3260 Parser.eatToEndOfStatement();
3261 return Error(Loc, "unexpected token in argument list");
3263 // Parse bracket and parenthesis suffixes before we iterate
3264 if (getLexer().is(AsmToken::LBrac)) {
3265 if (parseBracketSuffix(Name, Operands))
3267 } else if (getLexer().is(AsmToken::LParen) &&
3268 parseParenSuffix(Name, Operands))
3272 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3273 SMLoc Loc = getLexer().getLoc();
3274 Parser.eatToEndOfStatement();
3275 return Error(Loc, "unexpected token in argument list");
3277 Parser.Lex(); // Consume the EndOfStatement.
3281 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3282 MCAsmParser &Parser = getParser();
3283 SMLoc Loc = getLexer().getLoc();
3284 Parser.eatToEndOfStatement();
3285 return Error(Loc, ErrorMsg);
3288 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3289 return Error(Loc, ErrorMsg);
3292 bool MipsAsmParser::parseSetNoAtDirective() {
3293 MCAsmParser &Parser = getParser();
3294 // Line should look like: ".set noat".
3296 // Set the $at register to $0.
3297 AssemblerOptions.back()->setATReg(0);
3299 Parser.Lex(); // Eat "noat".
3301 // If this is not the end of the statement, report an error.
3302 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3303 reportParseError("unexpected token, expected end of statement");
3307 getTargetStreamer().emitDirectiveSetNoAt();
3308 Parser.Lex(); // Consume the EndOfStatement.
3312 bool MipsAsmParser::parseSetAtDirective() {
3313 // Line can be: ".set at", which sets $at to $1
3314 // or ".set at=$reg", which sets $at to $reg.
3315 MCAsmParser &Parser = getParser();
3316 Parser.Lex(); // Eat "at".
3318 if (getLexer().is(AsmToken::EndOfStatement)) {
3319 // No register was specified, so we set $at to $1.
3320 AssemblerOptions.back()->setATReg(1);
3322 getTargetStreamer().emitDirectiveSetAt();
3323 Parser.Lex(); // Consume the EndOfStatement.
3327 if (getLexer().isNot(AsmToken::Equal)) {
3328 reportParseError("unexpected token, expected equals sign");
3331 Parser.Lex(); // Eat "=".
3333 if (getLexer().isNot(AsmToken::Dollar)) {
3334 if (getLexer().is(AsmToken::EndOfStatement)) {
3335 reportParseError("no register specified");
3338 reportParseError("unexpected token, expected dollar sign '$'");
3342 Parser.Lex(); // Eat "$".
3344 // Find out what "reg" is.
3346 const AsmToken &Reg = Parser.getTok();
3347 if (Reg.is(AsmToken::Identifier)) {
3348 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3349 } else if (Reg.is(AsmToken::Integer)) {
3350 AtRegNo = Reg.getIntVal();
3352 reportParseError("unexpected token, expected identifier or integer");
3356 // Check if $reg is a valid register. If it is, set $at to $reg.
3357 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3358 reportParseError("invalid register");
3361 Parser.Lex(); // Eat "reg".
3363 // If this is not the end of the statement, report an error.
3364 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3365 reportParseError("unexpected token, expected end of statement");
3369 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3371 Parser.Lex(); // Consume the EndOfStatement.
3375 bool MipsAsmParser::parseSetReorderDirective() {
3376 MCAsmParser &Parser = getParser();
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");
3383 AssemblerOptions.back()->setReorder();
3384 getTargetStreamer().emitDirectiveSetReorder();
3385 Parser.Lex(); // Consume the EndOfStatement.
3389 bool MipsAsmParser::parseSetNoReorderDirective() {
3390 MCAsmParser &Parser = getParser();
3392 // If this is not the end of the statement, report an error.
3393 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3394 reportParseError("unexpected token, expected end of statement");
3397 AssemblerOptions.back()->setNoReorder();
3398 getTargetStreamer().emitDirectiveSetNoReorder();
3399 Parser.Lex(); // Consume the EndOfStatement.
3403 bool MipsAsmParser::parseSetMacroDirective() {
3404 MCAsmParser &Parser = getParser();
3406 // If this is not the end of the statement, report an error.
3407 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3408 reportParseError("unexpected token, expected end of statement");
3411 AssemblerOptions.back()->setMacro();
3412 Parser.Lex(); // Consume the EndOfStatement.
3416 bool MipsAsmParser::parseSetNoMacroDirective() {
3417 MCAsmParser &Parser = getParser();
3419 // If this is not the end of the statement, report an error.
3420 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3421 reportParseError("unexpected token, expected end of statement");
3424 if (AssemblerOptions.back()->isReorder()) {
3425 reportParseError("`noreorder' must be set before `nomacro'");
3428 AssemblerOptions.back()->setNoMacro();
3429 Parser.Lex(); // Consume the EndOfStatement.
3433 bool MipsAsmParser::parseSetMsaDirective() {
3434 MCAsmParser &Parser = getParser();
3437 // If this is not the end of the statement, report an error.
3438 if (getLexer().isNot(AsmToken::EndOfStatement))
3439 return reportParseError("unexpected token, expected end of statement");
3441 setFeatureBits(Mips::FeatureMSA, "msa");
3442 getTargetStreamer().emitDirectiveSetMsa();
3446 bool MipsAsmParser::parseSetNoMsaDirective() {
3447 MCAsmParser &Parser = getParser();
3450 // If this is not the end of the statement, report an error.
3451 if (getLexer().isNot(AsmToken::EndOfStatement))
3452 return reportParseError("unexpected token, expected end of statement");
3454 clearFeatureBits(Mips::FeatureMSA, "msa");
3455 getTargetStreamer().emitDirectiveSetNoMsa();
3459 bool MipsAsmParser::parseSetNoDspDirective() {
3460 MCAsmParser &Parser = getParser();
3461 Parser.Lex(); // Eat "nodsp".
3463 // If this is not the end of the statement, report an error.
3464 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3465 reportParseError("unexpected token, expected end of statement");
3469 clearFeatureBits(Mips::FeatureDSP, "dsp");
3470 getTargetStreamer().emitDirectiveSetNoDsp();
3474 bool MipsAsmParser::parseSetMips16Directive() {
3475 MCAsmParser &Parser = getParser();
3476 Parser.Lex(); // Eat "mips16".
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 setFeatureBits(Mips::FeatureMips16, "mips16");
3485 getTargetStreamer().emitDirectiveSetMips16();
3486 Parser.Lex(); // Consume the EndOfStatement.
3490 bool MipsAsmParser::parseSetNoMips16Directive() {
3491 MCAsmParser &Parser = getParser();
3492 Parser.Lex(); // Eat "nomips16".
3494 // If this is not the end of the statement, report an error.
3495 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3496 reportParseError("unexpected token, expected end of statement");
3500 clearFeatureBits(Mips::FeatureMips16, "mips16");
3501 getTargetStreamer().emitDirectiveSetNoMips16();
3502 Parser.Lex(); // Consume the EndOfStatement.
3506 bool MipsAsmParser::parseSetFpDirective() {
3507 MCAsmParser &Parser = getParser();
3508 MipsABIFlagsSection::FpABIKind FpAbiVal;
3509 // Line can be: .set fp=32
3512 Parser.Lex(); // Eat fp token
3513 AsmToken Tok = Parser.getTok();
3514 if (Tok.isNot(AsmToken::Equal)) {
3515 reportParseError("unexpected token, expected equals sign '='");
3518 Parser.Lex(); // Eat '=' token.
3519 Tok = Parser.getTok();
3521 if (!parseFpABIValue(FpAbiVal, ".set"))
3524 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3525 reportParseError("unexpected token, expected end of statement");
3528 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3529 Parser.Lex(); // Consume the EndOfStatement.
3533 bool MipsAsmParser::parseSetPopDirective() {
3534 MCAsmParser &Parser = getParser();
3535 SMLoc Loc = getLexer().getLoc();
3538 if (getLexer().isNot(AsmToken::EndOfStatement))
3539 return reportParseError("unexpected token, expected end of statement");
3541 // Always keep an element on the options "stack" to prevent the user
3542 // from changing the initial options. This is how we remember them.
3543 if (AssemblerOptions.size() == 2)
3544 return reportParseError(Loc, ".set pop with no .set push");
3546 AssemblerOptions.pop_back();
3547 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3549 getTargetStreamer().emitDirectiveSetPop();
3553 bool MipsAsmParser::parseSetPushDirective() {
3554 MCAsmParser &Parser = getParser();
3556 if (getLexer().isNot(AsmToken::EndOfStatement))
3557 return reportParseError("unexpected token, expected end of statement");
3559 // Create a copy of the current assembler options environment and push it.
3560 AssemblerOptions.push_back(
3561 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3563 getTargetStreamer().emitDirectiveSetPush();
3567 bool MipsAsmParser::parseSetAssignment() {
3569 const MCExpr *Value;
3570 MCAsmParser &Parser = getParser();
3572 if (Parser.parseIdentifier(Name))
3573 reportParseError("expected identifier after .set");
3575 if (getLexer().isNot(AsmToken::Comma))
3576 return reportParseError("unexpected token, expected comma");
3579 if (Parser.parseExpression(Value))
3580 return reportParseError("expected valid expression after comma");
3582 // Check if the Name already exists as a symbol.
3583 MCSymbol *Sym = getContext().LookupSymbol(Name);
3585 return reportParseError("symbol already defined");
3586 Sym = getContext().GetOrCreateSymbol(Name);
3587 Sym->setVariableValue(Value);
3592 bool MipsAsmParser::parseSetMips0Directive() {
3593 MCAsmParser &Parser = getParser();
3595 if (getLexer().isNot(AsmToken::EndOfStatement))
3596 return reportParseError("unexpected token, expected end of statement");
3598 // Reset assembler options to their initial values.
3599 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3600 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3602 getTargetStreamer().emitDirectiveSetMips0();
3606 bool MipsAsmParser::parseSetArchDirective() {
3607 MCAsmParser &Parser = getParser();
3609 if (getLexer().isNot(AsmToken::Equal))
3610 return reportParseError("unexpected token, expected equals sign");
3614 if (Parser.parseIdentifier(Arch))
3615 return reportParseError("expected arch identifier");
3617 StringRef ArchFeatureName =
3618 StringSwitch<StringRef>(Arch)
3619 .Case("mips1", "mips1")
3620 .Case("mips2", "mips2")
3621 .Case("mips3", "mips3")
3622 .Case("mips4", "mips4")
3623 .Case("mips5", "mips5")
3624 .Case("mips32", "mips32")
3625 .Case("mips32r2", "mips32r2")
3626 .Case("mips32r3", "mips32r3")
3627 .Case("mips32r5", "mips32r5")
3628 .Case("mips32r6", "mips32r6")
3629 .Case("mips64", "mips64")
3630 .Case("mips64r2", "mips64r2")
3631 .Case("mips64r3", "mips64r3")
3632 .Case("mips64r5", "mips64r5")
3633 .Case("mips64r6", "mips64r6")
3634 .Case("cnmips", "cnmips")
3635 .Case("r4000", "mips3") // This is an implementation of Mips3.
3638 if (ArchFeatureName.empty())
3639 return reportParseError("unsupported architecture");
3641 selectArch(ArchFeatureName);
3642 getTargetStreamer().emitDirectiveSetArch(Arch);
3646 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3647 MCAsmParser &Parser = getParser();
3649 if (getLexer().isNot(AsmToken::EndOfStatement))
3650 return reportParseError("unexpected token, expected end of statement");
3654 llvm_unreachable("Unimplemented feature");
3655 case Mips::FeatureDSP:
3656 setFeatureBits(Mips::FeatureDSP, "dsp");
3657 getTargetStreamer().emitDirectiveSetDsp();
3659 case Mips::FeatureMicroMips:
3660 getTargetStreamer().emitDirectiveSetMicroMips();
3662 case Mips::FeatureMips1:
3663 selectArch("mips1");
3664 getTargetStreamer().emitDirectiveSetMips1();
3666 case Mips::FeatureMips2:
3667 selectArch("mips2");
3668 getTargetStreamer().emitDirectiveSetMips2();
3670 case Mips::FeatureMips3:
3671 selectArch("mips3");
3672 getTargetStreamer().emitDirectiveSetMips3();
3674 case Mips::FeatureMips4:
3675 selectArch("mips4");
3676 getTargetStreamer().emitDirectiveSetMips4();
3678 case Mips::FeatureMips5:
3679 selectArch("mips5");
3680 getTargetStreamer().emitDirectiveSetMips5();
3682 case Mips::FeatureMips32:
3683 selectArch("mips32");
3684 getTargetStreamer().emitDirectiveSetMips32();
3686 case Mips::FeatureMips32r2:
3687 selectArch("mips32r2");
3688 getTargetStreamer().emitDirectiveSetMips32R2();
3690 case Mips::FeatureMips32r3:
3691 selectArch("mips32r3");
3692 getTargetStreamer().emitDirectiveSetMips32R3();
3694 case Mips::FeatureMips32r5:
3695 selectArch("mips32r5");
3696 getTargetStreamer().emitDirectiveSetMips32R5();
3698 case Mips::FeatureMips32r6:
3699 selectArch("mips32r6");
3700 getTargetStreamer().emitDirectiveSetMips32R6();
3702 case Mips::FeatureMips64:
3703 selectArch("mips64");
3704 getTargetStreamer().emitDirectiveSetMips64();
3706 case Mips::FeatureMips64r2:
3707 selectArch("mips64r2");
3708 getTargetStreamer().emitDirectiveSetMips64R2();
3710 case Mips::FeatureMips64r3:
3711 selectArch("mips64r3");
3712 getTargetStreamer().emitDirectiveSetMips64R3();
3714 case Mips::FeatureMips64r5:
3715 selectArch("mips64r5");
3716 getTargetStreamer().emitDirectiveSetMips64R5();
3718 case Mips::FeatureMips64r6:
3719 selectArch("mips64r6");
3720 getTargetStreamer().emitDirectiveSetMips64R6();
3726 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3727 MCAsmParser &Parser = getParser();
3728 if (getLexer().isNot(AsmToken::Comma)) {
3729 SMLoc Loc = getLexer().getLoc();
3730 Parser.eatToEndOfStatement();
3731 return Error(Loc, ErrorStr);
3734 Parser.Lex(); // Eat the comma.
3738 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3739 if (AssemblerOptions.back()->isReorder())
3740 Warning(Loc, ".cpload should be inside a noreorder section");
3742 if (inMips16Mode()) {
3743 reportParseError(".cpload is not supported in Mips16 mode");
3747 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3748 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3749 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3750 reportParseError("expected register containing function address");
3754 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3755 if (!RegOpnd.isGPRAsmReg()) {
3756 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3760 // If this is not the end of the statement, report an error.
3761 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3762 reportParseError("unexpected token, expected end of statement");
3766 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3770 bool MipsAsmParser::parseDirectiveCPSetup() {
3771 MCAsmParser &Parser = getParser();
3774 bool SaveIsReg = true;
3776 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3777 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3778 if (ResTy == MatchOperand_NoMatch) {
3779 reportParseError("expected register containing function address");
3780 Parser.eatToEndOfStatement();
3784 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3785 if (!FuncRegOpnd.isGPRAsmReg()) {
3786 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3787 Parser.eatToEndOfStatement();
3791 FuncReg = FuncRegOpnd.getGPR32Reg();
3794 if (!eatComma("unexpected token, expected comma"))
3797 ResTy = parseAnyRegister(TmpReg);
3798 if (ResTy == MatchOperand_NoMatch) {
3799 const AsmToken &Tok = Parser.getTok();
3800 if (Tok.is(AsmToken::Integer)) {
3801 Save = Tok.getIntVal();
3805 reportParseError("expected save register or stack offset");
3806 Parser.eatToEndOfStatement();
3810 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3811 if (!SaveOpnd.isGPRAsmReg()) {
3812 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3813 Parser.eatToEndOfStatement();
3816 Save = SaveOpnd.getGPR32Reg();
3819 if (!eatComma("unexpected token, expected comma"))
3823 if (Parser.parseExpression(Expr)) {
3824 reportParseError("expected expression");
3828 if (Expr->getKind() != MCExpr::SymbolRef) {
3829 reportParseError("expected symbol");
3832 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3834 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3839 bool MipsAsmParser::parseDirectiveNaN() {
3840 MCAsmParser &Parser = getParser();
3841 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3842 const AsmToken &Tok = Parser.getTok();
3844 if (Tok.getString() == "2008") {
3846 getTargetStreamer().emitDirectiveNaN2008();
3848 } else if (Tok.getString() == "legacy") {
3850 getTargetStreamer().emitDirectiveNaNLegacy();
3854 // If we don't recognize the option passed to the .nan
3855 // directive (e.g. no option or unknown option), emit an error.
3856 reportParseError("invalid option in .nan directive");
3860 bool MipsAsmParser::parseDirectiveSet() {
3861 MCAsmParser &Parser = getParser();
3862 // Get the next token.
3863 const AsmToken &Tok = Parser.getTok();
3865 if (Tok.getString() == "noat") {
3866 return parseSetNoAtDirective();
3867 } else if (Tok.getString() == "at") {
3868 return parseSetAtDirective();
3869 } else if (Tok.getString() == "arch") {
3870 return parseSetArchDirective();
3871 } else if (Tok.getString() == "fp") {
3872 return parseSetFpDirective();
3873 } else if (Tok.getString() == "pop") {
3874 return parseSetPopDirective();
3875 } else if (Tok.getString() == "push") {
3876 return parseSetPushDirective();
3877 } else if (Tok.getString() == "reorder") {
3878 return parseSetReorderDirective();
3879 } else if (Tok.getString() == "noreorder") {
3880 return parseSetNoReorderDirective();
3881 } else if (Tok.getString() == "macro") {
3882 return parseSetMacroDirective();
3883 } else if (Tok.getString() == "nomacro") {
3884 return parseSetNoMacroDirective();
3885 } else if (Tok.getString() == "mips16") {
3886 return parseSetMips16Directive();
3887 } else if (Tok.getString() == "nomips16") {
3888 return parseSetNoMips16Directive();
3889 } else if (Tok.getString() == "nomicromips") {
3890 getTargetStreamer().emitDirectiveSetNoMicroMips();
3891 Parser.eatToEndOfStatement();
3893 } else if (Tok.getString() == "micromips") {
3894 return parseSetFeature(Mips::FeatureMicroMips);
3895 } else if (Tok.getString() == "mips0") {
3896 return parseSetMips0Directive();
3897 } else if (Tok.getString() == "mips1") {
3898 return parseSetFeature(Mips::FeatureMips1);
3899 } else if (Tok.getString() == "mips2") {
3900 return parseSetFeature(Mips::FeatureMips2);
3901 } else if (Tok.getString() == "mips3") {
3902 return parseSetFeature(Mips::FeatureMips3);
3903 } else if (Tok.getString() == "mips4") {
3904 return parseSetFeature(Mips::FeatureMips4);
3905 } else if (Tok.getString() == "mips5") {
3906 return parseSetFeature(Mips::FeatureMips5);
3907 } else if (Tok.getString() == "mips32") {
3908 return parseSetFeature(Mips::FeatureMips32);
3909 } else if (Tok.getString() == "mips32r2") {
3910 return parseSetFeature(Mips::FeatureMips32r2);
3911 } else if (Tok.getString() == "mips32r3") {
3912 return parseSetFeature(Mips::FeatureMips32r3);
3913 } else if (Tok.getString() == "mips32r5") {
3914 return parseSetFeature(Mips::FeatureMips32r5);
3915 } else if (Tok.getString() == "mips32r6") {
3916 return parseSetFeature(Mips::FeatureMips32r6);
3917 } else if (Tok.getString() == "mips64") {
3918 return parseSetFeature(Mips::FeatureMips64);
3919 } else if (Tok.getString() == "mips64r2") {
3920 return parseSetFeature(Mips::FeatureMips64r2);
3921 } else if (Tok.getString() == "mips64r3") {
3922 return parseSetFeature(Mips::FeatureMips64r3);
3923 } else if (Tok.getString() == "mips64r5") {
3924 return parseSetFeature(Mips::FeatureMips64r5);
3925 } else if (Tok.getString() == "mips64r6") {
3926 return parseSetFeature(Mips::FeatureMips64r6);
3927 } else if (Tok.getString() == "dsp") {
3928 return parseSetFeature(Mips::FeatureDSP);
3929 } else if (Tok.getString() == "nodsp") {
3930 return parseSetNoDspDirective();
3931 } else if (Tok.getString() == "msa") {
3932 return parseSetMsaDirective();
3933 } else if (Tok.getString() == "nomsa") {
3934 return parseSetNoMsaDirective();
3936 // It is just an identifier, look for an assignment.
3937 parseSetAssignment();
3944 /// parseDataDirective
3945 /// ::= .word [ expression (, expression)* ]
3946 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3947 MCAsmParser &Parser = getParser();
3948 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3950 const MCExpr *Value;
3951 if (getParser().parseExpression(Value))
3954 getParser().getStreamer().EmitValue(Value, Size);
3956 if (getLexer().is(AsmToken::EndOfStatement))
3959 if (getLexer().isNot(AsmToken::Comma))
3960 return Error(L, "unexpected token, expected comma");
3969 /// parseDirectiveGpWord
3970 /// ::= .gpword local_sym
3971 bool MipsAsmParser::parseDirectiveGpWord() {
3972 MCAsmParser &Parser = getParser();
3973 const MCExpr *Value;
3974 // EmitGPRel32Value requires an expression, so we are using base class
3975 // method to evaluate the expression.
3976 if (getParser().parseExpression(Value))
3978 getParser().getStreamer().EmitGPRel32Value(Value);
3980 if (getLexer().isNot(AsmToken::EndOfStatement))
3981 return Error(getLexer().getLoc(),
3982 "unexpected token, expected end of statement");
3983 Parser.Lex(); // Eat EndOfStatement token.
3987 /// parseDirectiveGpDWord
3988 /// ::= .gpdword local_sym
3989 bool MipsAsmParser::parseDirectiveGpDWord() {
3990 MCAsmParser &Parser = getParser();
3991 const MCExpr *Value;
3992 // EmitGPRel64Value requires an expression, so we are using base class
3993 // method to evaluate the expression.
3994 if (getParser().parseExpression(Value))
3996 getParser().getStreamer().EmitGPRel64Value(Value);
3998 if (getLexer().isNot(AsmToken::EndOfStatement))
3999 return Error(getLexer().getLoc(),
4000 "unexpected token, expected end of statement");
4001 Parser.Lex(); // Eat EndOfStatement token.
4005 bool MipsAsmParser::parseDirectiveOption() {
4006 MCAsmParser &Parser = getParser();
4007 // Get the option token.
4008 AsmToken Tok = Parser.getTok();
4009 // At the moment only identifiers are supported.
4010 if (Tok.isNot(AsmToken::Identifier)) {
4011 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4012 Parser.eatToEndOfStatement();
4016 StringRef Option = Tok.getIdentifier();
4018 if (Option == "pic0") {
4019 getTargetStreamer().emitDirectiveOptionPic0();
4021 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4022 Error(Parser.getTok().getLoc(),
4023 "unexpected token, expected end of statement");
4024 Parser.eatToEndOfStatement();
4029 if (Option == "pic2") {
4030 getTargetStreamer().emitDirectiveOptionPic2();
4032 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4033 Error(Parser.getTok().getLoc(),
4034 "unexpected token, expected end of statement");
4035 Parser.eatToEndOfStatement();
4041 Warning(Parser.getTok().getLoc(),
4042 "unknown option, expected 'pic0' or 'pic2'");
4043 Parser.eatToEndOfStatement();
4047 /// parseDirectiveModule
4048 /// ::= .module oddspreg
4049 /// ::= .module nooddspreg
4050 /// ::= .module fp=value
4051 bool MipsAsmParser::parseDirectiveModule() {
4052 MCAsmParser &Parser = getParser();
4053 MCAsmLexer &Lexer = getLexer();
4054 SMLoc L = Lexer.getLoc();
4056 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4057 // TODO : get a better message.
4058 reportParseError(".module directive must appear before any code");
4063 if (Parser.parseIdentifier(Option)) {
4064 reportParseError("expected .module option identifier");
4068 if (Option == "oddspreg") {
4069 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4070 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4072 // If this is not the end of the statement, report an error.
4073 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4074 reportParseError("unexpected token, expected end of statement");
4078 return false; // parseDirectiveModule has finished successfully.
4079 } else if (Option == "nooddspreg") {
4081 Error(L, "'.module nooddspreg' requires the O32 ABI");
4085 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4086 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4088 // If this is not the end of the statement, report an error.
4089 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4090 reportParseError("unexpected token, expected end of statement");
4094 return false; // parseDirectiveModule has finished successfully.
4095 } else if (Option == "fp") {
4096 return parseDirectiveModuleFP();
4098 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4102 /// parseDirectiveModuleFP
4106 bool MipsAsmParser::parseDirectiveModuleFP() {
4107 MCAsmParser &Parser = getParser();
4108 MCAsmLexer &Lexer = getLexer();
4110 if (Lexer.isNot(AsmToken::Equal)) {
4111 reportParseError("unexpected token, expected equals sign '='");
4114 Parser.Lex(); // Eat '=' token.
4116 MipsABIFlagsSection::FpABIKind FpABI;
4117 if (!parseFpABIValue(FpABI, ".module"))
4120 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4121 reportParseError("unexpected token, expected end of statement");
4125 // Emit appropriate flags.
4126 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4127 Parser.Lex(); // Consume the EndOfStatement.
4131 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4132 StringRef Directive) {
4133 MCAsmParser &Parser = getParser();
4134 MCAsmLexer &Lexer = getLexer();
4136 if (Lexer.is(AsmToken::Identifier)) {
4137 StringRef Value = Parser.getTok().getString();
4140 if (Value != "xx") {
4141 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4146 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4150 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4154 if (Lexer.is(AsmToken::Integer)) {
4155 unsigned Value = Parser.getTok().getIntVal();
4158 if (Value != 32 && Value != 64) {
4159 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4165 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4169 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4171 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4179 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4180 MCAsmParser &Parser = getParser();
4181 StringRef IDVal = DirectiveID.getString();
4183 if (IDVal == ".cpload")
4184 return parseDirectiveCpLoad(DirectiveID.getLoc());
4185 if (IDVal == ".dword") {
4186 parseDataDirective(8, DirectiveID.getLoc());
4189 if (IDVal == ".ent") {
4190 StringRef SymbolName;
4192 if (Parser.parseIdentifier(SymbolName)) {
4193 reportParseError("expected identifier after .ent");
4197 // There's an undocumented extension that allows an integer to
4198 // follow the name of the procedure which AFAICS is ignored by GAS.
4199 // Example: .ent foo,2
4200 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4201 if (getLexer().isNot(AsmToken::Comma)) {
4202 // Even though we accept this undocumented extension for compatibility
4203 // reasons, the additional integer argument does not actually change
4204 // the behaviour of the '.ent' directive, so we would like to discourage
4205 // its use. We do this by not referring to the extended version in
4206 // error messages which are not directly related to its use.
4207 reportParseError("unexpected token, expected end of statement");
4210 Parser.Lex(); // Eat the comma.
4211 const MCExpr *DummyNumber;
4212 int64_t DummyNumberVal;
4213 // If the user was explicitly trying to use the extended version,
4214 // we still give helpful extension-related error messages.
4215 if (Parser.parseExpression(DummyNumber)) {
4216 reportParseError("expected number after comma");
4219 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4220 reportParseError("expected an absolute expression after comma");
4225 // If this is not the end of the statement, report an error.
4226 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4227 reportParseError("unexpected token, expected end of statement");
4231 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4233 getTargetStreamer().emitDirectiveEnt(*Sym);
4238 if (IDVal == ".end") {
4239 StringRef SymbolName;
4241 if (Parser.parseIdentifier(SymbolName)) {
4242 reportParseError("expected identifier after .end");
4246 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4247 reportParseError("unexpected token, expected end of statement");
4251 if (CurrentFn == nullptr) {
4252 reportParseError(".end used without .ent");
4256 if ((SymbolName != CurrentFn->getName())) {
4257 reportParseError(".end symbol does not match .ent symbol");
4261 getTargetStreamer().emitDirectiveEnd(SymbolName);
4262 CurrentFn = nullptr;
4266 if (IDVal == ".frame") {
4267 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4268 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4269 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4270 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4271 reportParseError("expected stack register");
4275 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4276 if (!StackRegOpnd.isGPRAsmReg()) {
4277 reportParseError(StackRegOpnd.getStartLoc(),
4278 "expected general purpose register");
4281 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4283 if (Parser.getTok().is(AsmToken::Comma))
4286 reportParseError("unexpected token, expected comma");
4290 // Parse the frame size.
4291 const MCExpr *FrameSize;
4292 int64_t FrameSizeVal;
4294 if (Parser.parseExpression(FrameSize)) {
4295 reportParseError("expected frame size value");
4299 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4300 reportParseError("frame size not an absolute expression");
4304 if (Parser.getTok().is(AsmToken::Comma))
4307 reportParseError("unexpected token, expected comma");
4311 // Parse the return register.
4313 ResTy = parseAnyRegister(TmpReg);
4314 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4315 reportParseError("expected return register");
4319 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4320 if (!ReturnRegOpnd.isGPRAsmReg()) {
4321 reportParseError(ReturnRegOpnd.getStartLoc(),
4322 "expected general purpose register");
4326 // If this is not the end of the statement, report an error.
4327 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4328 reportParseError("unexpected token, expected end of statement");
4332 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4333 ReturnRegOpnd.getGPR32Reg());
4337 if (IDVal == ".set") {
4338 return parseDirectiveSet();
4341 if (IDVal == ".mask" || IDVal == ".fmask") {
4342 // .mask bitmask, frame_offset
4343 // bitmask: One bit for each register used.
4344 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4345 // first register is expected to be saved.
4347 // .mask 0x80000000, -4
4348 // .fmask 0x80000000, -4
4351 // Parse the bitmask
4352 const MCExpr *BitMask;
4355 if (Parser.parseExpression(BitMask)) {
4356 reportParseError("expected bitmask value");
4360 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4361 reportParseError("bitmask not an absolute expression");
4365 if (Parser.getTok().is(AsmToken::Comma))
4368 reportParseError("unexpected token, expected comma");
4372 // Parse the frame_offset
4373 const MCExpr *FrameOffset;
4374 int64_t FrameOffsetVal;
4376 if (Parser.parseExpression(FrameOffset)) {
4377 reportParseError("expected frame offset value");
4381 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4382 reportParseError("frame offset not an absolute expression");
4386 // If this is not the end of the statement, report an error.
4387 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4388 reportParseError("unexpected token, expected end of statement");
4392 if (IDVal == ".mask")
4393 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4395 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4399 if (IDVal == ".nan")
4400 return parseDirectiveNaN();
4402 if (IDVal == ".gpword") {
4403 parseDirectiveGpWord();
4407 if (IDVal == ".gpdword") {
4408 parseDirectiveGpDWord();
4412 if (IDVal == ".word") {
4413 parseDataDirective(4, DirectiveID.getLoc());
4417 if (IDVal == ".option")
4418 return parseDirectiveOption();
4420 if (IDVal == ".abicalls") {
4421 getTargetStreamer().emitDirectiveAbiCalls();
4422 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4423 Error(Parser.getTok().getLoc(),
4424 "unexpected token, expected end of statement");
4426 Parser.eatToEndOfStatement();
4431 if (IDVal == ".cpsetup")
4432 return parseDirectiveCPSetup();
4434 if (IDVal == ".module")
4435 return parseDirectiveModule();
4437 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4438 return parseInternalDirectiveReallowModule();
4443 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4444 // If this is not the end of the statement, report an error.
4445 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4446 reportParseError("unexpected token, expected end of statement");
4450 getTargetStreamer().reallowModuleDirective();
4452 getParser().Lex(); // Eat EndOfStatement token.
4456 extern "C" void LLVMInitializeMipsAsmParser() {
4457 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4458 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4459 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4460 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4463 #define GET_REGISTER_MATCHER
4464 #define GET_MATCHER_IMPLEMENTATION
4465 #include "MipsGenAsmMatcher.inc"