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);
59 bool isReorder() const { return Reorder; }
60 void setReorder() { Reorder = true; }
61 void setNoReorder() { Reorder = false; }
63 bool isMacro() const { return Macro; }
64 void setMacro() { Macro = true; }
65 void setNoMacro() { Macro = false; }
67 uint64_t getFeatures() const { return Features; }
68 void setFeatures(uint64_t Features_) { Features = Features_; }
70 // Set of features that are either architecture features or referenced
71 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
72 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
73 // The reason we need this mask is explained in the selectArch function.
74 // FIXME: Ideally we would like TableGen to generate this information.
75 static const uint64_t AllArchRelatedMask =
76 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
77 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
78 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
79 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
80 Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
81 Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
82 Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
83 Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
94 class MipsAsmParser : public MCTargetAsmParser {
95 MipsTargetStreamer &getTargetStreamer() {
96 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
97 return static_cast<MipsTargetStreamer &>(TS);
100 MCSubtargetInfo &STI;
102 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
103 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
104 // nullptr, which indicates that no function is currently
105 // selected. This usually happens after an '.end func'
108 // Print a warning along with its fix-it message at the given range.
109 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
110 SMRange Range, bool ShowColors = true);
112 #define GET_ASSEMBLER_HEADER
113 #include "MipsGenAsmMatcher.inc"
115 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
117 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
118 OperandVector &Operands, MCStreamer &Out,
120 bool MatchingInlineAsm) override;
122 /// Parse a register as used in CFI directives
123 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
125 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
127 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
129 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
130 SMLoc NameLoc, OperandVector &Operands) override;
132 bool ParseDirective(AsmToken DirectiveID) override;
134 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
136 MipsAsmParser::OperandMatchResultTy
137 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
138 StringRef Identifier, SMLoc S);
140 MipsAsmParser::OperandMatchResultTy
141 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
143 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
147 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
149 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
151 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
153 MipsAsmParser::OperandMatchResultTy
154 parseRegisterPair (OperandVector &Operands);
156 MipsAsmParser::OperandMatchResultTy
157 parseMovePRegPair(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy
160 parseRegisterList (OperandVector &Operands);
162 bool searchSymbolAlias(OperandVector &Operands);
164 bool parseOperand(OperandVector &, StringRef Mnemonic);
166 bool needsExpansion(MCInst &Inst);
168 // Expands assembly pseudo instructions.
169 // Returns false on success, true otherwise.
170 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
171 SmallVectorImpl<MCInst> &Instructions);
173 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
174 SmallVectorImpl<MCInst> &Instructions);
176 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
184 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
185 SmallVectorImpl<MCInst> &Instructions);
187 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
188 SmallVectorImpl<MCInst> &Instructions);
190 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
194 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
195 SmallVectorImpl<MCInst> &Instructions);
197 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 bool reportParseError(Twine ErrorMsg);
201 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
203 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
204 bool parseRelocOperand(const MCExpr *&Res);
206 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
208 bool isEvaluated(const MCExpr *Expr);
209 bool parseSetMips0Directive();
210 bool parseSetArchDirective();
211 bool parseSetFeature(uint64_t Feature);
212 bool parseDirectiveCpLoad(SMLoc Loc);
213 bool parseDirectiveCPSetup();
214 bool parseDirectiveNaN();
215 bool parseDirectiveSet();
216 bool parseDirectiveOption();
218 bool parseSetAtDirective();
219 bool parseSetNoAtDirective();
220 bool parseSetMacroDirective();
221 bool parseSetNoMacroDirective();
222 bool parseSetMsaDirective();
223 bool parseSetNoMsaDirective();
224 bool parseSetNoDspDirective();
225 bool parseSetReorderDirective();
226 bool parseSetNoReorderDirective();
227 bool parseSetMips16Directive();
228 bool parseSetNoMips16Directive();
229 bool parseSetFpDirective();
230 bool parseSetPopDirective();
231 bool parseSetPushDirective();
233 bool parseSetAssignment();
235 bool parseDataDirective(unsigned Size, SMLoc L);
236 bool parseDirectiveGpWord();
237 bool parseDirectiveGpDWord();
238 bool parseDirectiveModule();
239 bool parseDirectiveModuleFP();
240 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
241 StringRef Directive);
243 bool parseInternalDirectiveReallowModule();
245 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
247 bool eatComma(StringRef ErrorStr);
249 int matchCPURegisterName(StringRef Symbol);
251 int matchHWRegsRegisterName(StringRef Symbol);
253 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
255 int matchFPURegisterName(StringRef Name);
257 int matchFCCRegisterName(StringRef Name);
259 int matchACRegisterName(StringRef Name);
261 int matchMSA128RegisterName(StringRef Name);
263 int matchMSA128CtrlRegisterName(StringRef Name);
265 unsigned getReg(int RC, int RegNo);
267 unsigned getGPR(int RegNo);
269 int getATReg(SMLoc Loc);
271 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
272 SmallVectorImpl<MCInst> &Instructions);
274 // Helper function that checks if the value of a vector index is within the
275 // boundaries of accepted values for each RegisterKind
276 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
277 bool validateMSAIndex(int Val, int RegKind);
279 // Selects a new architecture by updating the FeatureBits with the necessary
280 // info including implied dependencies.
281 // Internally, it clears all the feature bits related to *any* architecture
282 // and selects the new one using the ToggleFeature functionality of the
283 // MCSubtargetInfo object that handles implied dependencies. The reason we
284 // clear all the arch related bits manually is because ToggleFeature only
285 // clears the features that imply the feature being cleared and not the
286 // features implied by the feature being cleared. This is easier to see
288 // --------------------------------------------------
289 // | Feature | Implies |
290 // | -------------------------------------------------|
291 // | FeatureMips1 | None |
292 // | FeatureMips2 | FeatureMips1 |
293 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
294 // | FeatureMips4 | FeatureMips3 |
296 // --------------------------------------------------
298 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
299 // FeatureMipsGP64 | FeatureMips1)
300 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
301 void selectArch(StringRef ArchFeature) {
302 uint64_t FeatureBits = STI.getFeatureBits();
303 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
304 STI.setFeatureBits(FeatureBits);
305 setAvailableFeatures(
306 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
307 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
310 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
311 if (!(STI.getFeatureBits() & Feature)) {
312 setAvailableFeatures(
313 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
315 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
318 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
319 if (STI.getFeatureBits() & Feature) {
320 setAvailableFeatures(
321 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
323 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
327 enum MipsMatchResultTy {
328 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
329 #define GET_OPERAND_DIAGNOSTIC_TYPES
330 #include "MipsGenAsmMatcher.inc"
331 #undef GET_OPERAND_DIAGNOSTIC_TYPES
335 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
336 const MCInstrInfo &MII, const MCTargetOptions &Options)
337 : MCTargetAsmParser(), STI(sti),
338 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
339 sti.getCPU(), Options)) {
340 MCAsmParserExtension::Initialize(parser);
342 // Initialize the set of available features.
343 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
345 // Remember the initial assembler options. The user can not modify these.
346 AssemblerOptions.push_back(
347 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
349 // Create an assembler options environment for the user to modify.
350 AssemblerOptions.push_back(
351 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
353 getTargetStreamer().updateABIInfo(*this);
355 if (!isABI_O32() && !useOddSPReg() != 0)
356 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
361 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
362 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
364 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
365 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
366 const MipsABIInfo &getABI() const { return ABI; }
367 bool isABI_N32() const { return ABI.IsN32(); }
368 bool isABI_N64() const { return ABI.IsN64(); }
369 bool isABI_O32() const { return ABI.IsO32(); }
370 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
372 bool useOddSPReg() const {
373 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
376 bool inMicroMipsMode() const {
377 return STI.getFeatureBits() & Mips::FeatureMicroMips;
379 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
380 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
381 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
382 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
383 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
384 bool hasMips32() const {
385 return (STI.getFeatureBits() & Mips::FeatureMips32);
387 bool hasMips64() const {
388 return (STI.getFeatureBits() & Mips::FeatureMips64);
390 bool hasMips32r2() const {
391 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
393 bool hasMips64r2() const {
394 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
396 bool hasMips32r3() const {
397 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
399 bool hasMips64r3() const {
400 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
402 bool hasMips32r5() const {
403 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
405 bool hasMips64r5() const {
406 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
408 bool hasMips32r6() const {
409 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
411 bool hasMips64r6() const {
412 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
414 bool hasCnMips() const {
415 return (STI.getFeatureBits() & Mips::FeatureCnMips);
417 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
418 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
419 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
421 bool inMips16Mode() const {
422 return STI.getFeatureBits() & Mips::FeatureMips16;
424 // TODO: see how can we get this info.
425 bool abiUsesSoftFloat() const { return false; }
427 /// Warn if RegNo is the current assembler temporary.
428 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
434 /// MipsOperand - Instances of this class represent a parsed Mips machine
436 class MipsOperand : public MCParsedAsmOperand {
438 /// Broad categories of register classes
439 /// The exact class is finalized by the render method.
441 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
442 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
444 RegKind_FCC = 4, /// FCC
445 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
446 RegKind_MSACtrl = 16, /// MSA control registers
447 RegKind_COP2 = 32, /// COP2
448 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
450 RegKind_CCR = 128, /// CCR
451 RegKind_HWRegs = 256, /// HWRegs
452 RegKind_COP3 = 512, /// COP3
454 /// Potentially any (e.g. $1)
455 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
456 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
457 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
462 k_Immediate, /// An immediate (possibly involving symbol references)
463 k_Memory, /// Base + Offset Memory Address
464 k_PhysRegister, /// A physical register from the Mips namespace
465 k_RegisterIndex, /// A register index in one or more RegKind.
466 k_Token, /// A simple token
467 k_RegList, /// A physical register list
468 k_RegPair /// A pair of physical register
472 MipsOperand(KindTy K, MipsAsmParser &Parser)
473 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
476 /// For diagnostics, and checking the assembler temporary
477 MipsAsmParser &AsmParser;
485 unsigned Num; /// Register Number
489 unsigned Index; /// Index into the register class
490 RegKind Kind; /// Bitfield of the kinds it could possibly be
491 const MCRegisterInfo *RegInfo;
504 SmallVector<unsigned, 10> *List;
509 struct PhysRegOp PhysReg;
510 struct RegIdxOp RegIdx;
513 struct RegListOp RegList;
516 SMLoc StartLoc, EndLoc;
518 /// Internal constructor for register kinds
519 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
520 const MCRegisterInfo *RegInfo,
522 MipsAsmParser &Parser) {
523 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
524 Op->RegIdx.Index = Index;
525 Op->RegIdx.RegInfo = RegInfo;
526 Op->RegIdx.Kind = RegKind;
533 /// Coerce the register to GPR32 and return the real register for the current
535 unsigned getGPR32Reg() const {
536 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
537 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
538 unsigned ClassID = Mips::GPR32RegClassID;
539 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
542 /// Coerce the register to GPR32 and return the real register for the current
544 unsigned getGPRMM16Reg() const {
545 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
546 unsigned ClassID = Mips::GPR32RegClassID;
547 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
550 /// Coerce the register to GPR64 and return the real register for the current
552 unsigned getGPR64Reg() const {
553 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
554 unsigned ClassID = Mips::GPR64RegClassID;
555 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
559 /// Coerce the register to AFGR64 and return the real register for the current
561 unsigned getAFGR64Reg() const {
562 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
563 if (RegIdx.Index % 2 != 0)
564 AsmParser.Warning(StartLoc, "Float register should be even.");
565 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
566 .getRegister(RegIdx.Index / 2);
569 /// Coerce the register to FGR64 and return the real register for the current
571 unsigned getFGR64Reg() const {
572 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
573 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
574 .getRegister(RegIdx.Index);
577 /// Coerce the register to FGR32 and return the real register for the current
579 unsigned getFGR32Reg() const {
580 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
581 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
582 .getRegister(RegIdx.Index);
585 /// Coerce the register to FGRH32 and return the real register for the current
587 unsigned getFGRH32Reg() const {
588 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
589 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
590 .getRegister(RegIdx.Index);
593 /// Coerce the register to FCC and return the real register for the current
595 unsigned getFCCReg() const {
596 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
597 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
598 .getRegister(RegIdx.Index);
601 /// Coerce the register to MSA128 and return the real register for the current
603 unsigned getMSA128Reg() const {
604 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
605 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
607 unsigned ClassID = Mips::MSA128BRegClassID;
608 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
611 /// Coerce the register to MSACtrl and return the real register for the
613 unsigned getMSACtrlReg() const {
614 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
615 unsigned ClassID = Mips::MSACtrlRegClassID;
616 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
619 /// Coerce the register to COP2 and return the real register for the
621 unsigned getCOP2Reg() const {
622 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
623 unsigned ClassID = Mips::COP2RegClassID;
624 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
627 /// Coerce the register to COP3 and return the real register for the
629 unsigned getCOP3Reg() const {
630 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
631 unsigned ClassID = Mips::COP3RegClassID;
632 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
635 /// Coerce the register to ACC64DSP and return the real register for the
637 unsigned getACC64DSPReg() const {
638 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
639 unsigned ClassID = Mips::ACC64DSPRegClassID;
640 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
643 /// Coerce the register to HI32DSP and return the real register for the
645 unsigned getHI32DSPReg() const {
646 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
647 unsigned ClassID = Mips::HI32DSPRegClassID;
648 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
651 /// Coerce the register to LO32DSP and return the real register for the
653 unsigned getLO32DSPReg() const {
654 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
655 unsigned ClassID = Mips::LO32DSPRegClassID;
656 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
659 /// Coerce the register to CCR and return the real register for the
661 unsigned getCCRReg() const {
662 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
663 unsigned ClassID = Mips::CCRRegClassID;
664 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
667 /// Coerce the register to HWRegs and return the real register for the
669 unsigned getHWRegsReg() const {
670 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
671 unsigned ClassID = Mips::HWRegsRegClassID;
672 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
676 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
677 // Add as immediate when possible. Null MCExpr = 0.
679 Inst.addOperand(MCOperand::CreateImm(0));
680 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
681 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
683 Inst.addOperand(MCOperand::CreateExpr(Expr));
686 void addRegOperands(MCInst &Inst, unsigned N) const {
687 llvm_unreachable("Use a custom parser instead");
690 /// Render the operand to an MCInst as a GPR32
691 /// Asserts if the wrong number of operands are requested, or the operand
692 /// is not a k_RegisterIndex compatible with RegKind_GPR
693 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
694 assert(N == 1 && "Invalid number of operands!");
695 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
698 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
699 assert(N == 1 && "Invalid number of operands!");
700 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
703 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
704 assert(N == 1 && "Invalid number of operands!");
705 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
708 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
709 assert(N == 1 && "Invalid number of operands!");
710 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
713 /// Render the operand to an MCInst as a GPR64
714 /// Asserts if the wrong number of operands are requested, or the operand
715 /// is not a k_RegisterIndex compatible with RegKind_GPR
716 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
717 assert(N == 1 && "Invalid number of operands!");
718 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
721 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
722 assert(N == 1 && "Invalid number of operands!");
723 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
726 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
727 assert(N == 1 && "Invalid number of operands!");
728 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
731 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
732 assert(N == 1 && "Invalid number of operands!");
733 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
734 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
735 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
736 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
740 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
741 assert(N == 1 && "Invalid number of operands!");
742 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
745 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
746 assert(N == 1 && "Invalid number of operands!");
747 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
750 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
751 assert(N == 1 && "Invalid number of operands!");
752 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
755 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
756 assert(N == 1 && "Invalid number of operands!");
757 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
760 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
761 assert(N == 1 && "Invalid number of operands!");
762 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
765 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
766 assert(N == 1 && "Invalid number of operands!");
767 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
770 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
771 assert(N == 1 && "Invalid number of operands!");
772 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
775 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
776 assert(N == 1 && "Invalid number of operands!");
777 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
780 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
781 assert(N == 1 && "Invalid number of operands!");
782 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
785 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
786 assert(N == 1 && "Invalid number of operands!");
787 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
790 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
791 assert(N == 1 && "Invalid number of operands!");
792 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
795 void addImmOperands(MCInst &Inst, unsigned N) const {
796 assert(N == 1 && "Invalid number of operands!");
797 const MCExpr *Expr = getImm();
801 void addMemOperands(MCInst &Inst, unsigned N) const {
802 assert(N == 2 && "Invalid number of operands!");
804 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
806 const MCExpr *Expr = getMemOff();
810 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
811 assert(N == 2 && "Invalid number of operands!");
813 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
815 const MCExpr *Expr = getMemOff();
819 void addRegListOperands(MCInst &Inst, unsigned N) const {
820 assert(N == 1 && "Invalid number of operands!");
822 for (auto RegNo : getRegList())
823 Inst.addOperand(MCOperand::CreateReg(RegNo));
826 void addRegPairOperands(MCInst &Inst, unsigned N) const {
827 assert(N == 2 && "Invalid number of operands!");
828 unsigned RegNo = getRegPair();
829 Inst.addOperand(MCOperand::CreateReg(RegNo++));
830 Inst.addOperand(MCOperand::CreateReg(RegNo));
833 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
834 assert(N == 2 && "Invalid number of operands!");
835 for (auto RegNo : getRegList())
836 Inst.addOperand(MCOperand::CreateReg(RegNo));
839 bool isReg() const override {
840 // As a special case until we sort out the definition of div/divu, pretend
841 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
842 if (isGPRAsmReg() && RegIdx.Index == 0)
845 return Kind == k_PhysRegister;
847 bool isRegIdx() const { return Kind == k_RegisterIndex; }
848 bool isImm() const override { return Kind == k_Immediate; }
849 bool isConstantImm() const {
850 return isImm() && dyn_cast<MCConstantExpr>(getImm());
852 bool isToken() const override {
853 // Note: It's not possible to pretend that other operand kinds are tokens.
854 // The matcher emitter checks tokens first.
855 return Kind == k_Token;
857 bool isMem() const override { return Kind == k_Memory; }
858 bool isConstantMemOff() const {
859 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
861 template <unsigned Bits> bool isMemWithSimmOffset() const {
862 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
864 bool isMemWithGRPMM16Base() const {
865 return isMem() && getMemBase()->isMM16AsmReg();
867 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
868 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
869 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
871 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
872 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
873 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
874 && (getMemBase()->getGPR32Reg() == Mips::SP);
876 bool isRegList16() const {
880 int Size = RegList.List->size();
881 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
882 RegList.List->back() != Mips::RA)
885 int PrevReg = *RegList.List->begin();
886 for (int i = 1; i < Size - 1; i++) {
887 int Reg = (*(RegList.List))[i];
888 if ( Reg != PrevReg + 1)
895 bool isInvNum() const { return Kind == k_Immediate; }
896 bool isLSAImm() const {
897 if (!isConstantImm())
899 int64_t Val = getConstantImm();
900 return 1 <= Val && Val <= 4;
902 bool isRegList() const { return Kind == k_RegList; }
903 bool isMovePRegPair() const {
904 if (Kind != k_RegList || RegList.List->size() != 2)
907 unsigned R0 = RegList.List->front();
908 unsigned R1 = RegList.List->back();
910 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
911 (R0 == Mips::A1 && R1 == Mips::A3) ||
912 (R0 == Mips::A2 && R1 == Mips::A3) ||
913 (R0 == Mips::A0 && R1 == Mips::S5) ||
914 (R0 == Mips::A0 && R1 == Mips::S6) ||
915 (R0 == Mips::A0 && R1 == Mips::A1) ||
916 (R0 == Mips::A0 && R1 == Mips::A2) ||
917 (R0 == Mips::A0 && R1 == Mips::A3))
923 StringRef getToken() const {
924 assert(Kind == k_Token && "Invalid access!");
925 return StringRef(Tok.Data, Tok.Length);
927 bool isRegPair() const { return Kind == k_RegPair; }
929 unsigned getReg() const override {
930 // As a special case until we sort out the definition of div/divu, pretend
931 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
932 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
933 RegIdx.Kind & RegKind_GPR)
934 return getGPR32Reg(); // FIXME: GPR64 too
936 assert(Kind == k_PhysRegister && "Invalid access!");
940 const MCExpr *getImm() const {
941 assert((Kind == k_Immediate) && "Invalid access!");
945 int64_t getConstantImm() const {
946 const MCExpr *Val = getImm();
947 return static_cast<const MCConstantExpr *>(Val)->getValue();
950 MipsOperand *getMemBase() const {
951 assert((Kind == k_Memory) && "Invalid access!");
955 const MCExpr *getMemOff() const {
956 assert((Kind == k_Memory) && "Invalid access!");
960 int64_t getConstantMemOff() const {
961 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
964 const SmallVectorImpl<unsigned> &getRegList() const {
965 assert((Kind == k_RegList) && "Invalid access!");
966 return *(RegList.List);
969 unsigned getRegPair() const {
970 assert((Kind == k_RegPair) && "Invalid access!");
974 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
975 MipsAsmParser &Parser) {
976 auto Op = make_unique<MipsOperand>(k_Token, Parser);
977 Op->Tok.Data = Str.data();
978 Op->Tok.Length = Str.size();
984 /// Create a numeric register (e.g. $1). The exact register remains
985 /// unresolved until an instruction successfully matches
986 static std::unique_ptr<MipsOperand>
987 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
988 SMLoc E, MipsAsmParser &Parser) {
989 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
990 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
993 /// Create a register that is definitely a GPR.
994 /// This is typically only used for named registers such as $gp.
995 static std::unique_ptr<MipsOperand>
996 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
997 MipsAsmParser &Parser) {
998 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1001 /// Create a register that is definitely a FGR.
1002 /// This is typically only used for named registers such as $f0.
1003 static std::unique_ptr<MipsOperand>
1004 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1005 MipsAsmParser &Parser) {
1006 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1009 /// Create a register that is definitely a HWReg.
1010 /// This is typically only used for named registers such as $hwr_cpunum.
1011 static std::unique_ptr<MipsOperand>
1012 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1013 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1014 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1017 /// Create a register that is definitely an FCC.
1018 /// This is typically only used for named registers such as $fcc0.
1019 static std::unique_ptr<MipsOperand>
1020 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1021 MipsAsmParser &Parser) {
1022 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1025 /// Create a register that is definitely an ACC.
1026 /// This is typically only used for named registers such as $ac0.
1027 static std::unique_ptr<MipsOperand>
1028 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1029 MipsAsmParser &Parser) {
1030 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1033 /// Create a register that is definitely an MSA128.
1034 /// This is typically only used for named registers such as $w0.
1035 static std::unique_ptr<MipsOperand>
1036 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1037 SMLoc E, MipsAsmParser &Parser) {
1038 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1041 /// Create a register that is definitely an MSACtrl.
1042 /// This is typically only used for named registers such as $msaaccess.
1043 static std::unique_ptr<MipsOperand>
1044 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1045 SMLoc E, MipsAsmParser &Parser) {
1046 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1049 static std::unique_ptr<MipsOperand>
1050 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1051 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1058 static std::unique_ptr<MipsOperand>
1059 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1060 SMLoc E, MipsAsmParser &Parser) {
1061 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1062 Op->Mem.Base = Base.release();
1069 static std::unique_ptr<MipsOperand>
1070 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1071 MipsAsmParser &Parser) {
1072 assert (Regs.size() > 0 && "Empty list not allowed");
1074 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1075 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1076 Op->StartLoc = StartLoc;
1077 Op->EndLoc = EndLoc;
1081 static std::unique_ptr<MipsOperand>
1082 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1083 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1084 Op->RegIdx.Index = RegNo;
1090 bool isGPRAsmReg() const {
1091 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1093 bool isMM16AsmReg() const {
1094 if (!(isRegIdx() && RegIdx.Kind))
1096 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1097 || RegIdx.Index == 16 || RegIdx.Index == 17);
1099 bool isMM16AsmRegZero() const {
1100 if (!(isRegIdx() && RegIdx.Kind))
1102 return (RegIdx.Index == 0 ||
1103 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1104 RegIdx.Index == 17);
1106 bool isMM16AsmRegMoveP() const {
1107 if (!(isRegIdx() && RegIdx.Kind))
1109 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1110 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1112 bool isFGRAsmReg() const {
1113 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1114 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1116 bool isHWRegsAsmReg() const {
1117 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1119 bool isCCRAsmReg() const {
1120 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1122 bool isFCCAsmReg() const {
1123 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1125 if (!AsmParser.hasEightFccRegisters())
1126 return RegIdx.Index == 0;
1127 return RegIdx.Index <= 7;
1129 bool isACCAsmReg() const {
1130 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1132 bool isCOP2AsmReg() const {
1133 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1135 bool isCOP3AsmReg() const {
1136 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1138 bool isMSA128AsmReg() const {
1139 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1141 bool isMSACtrlAsmReg() const {
1142 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1145 /// getStartLoc - Get the location of the first token of this operand.
1146 SMLoc getStartLoc() const override { return StartLoc; }
1147 /// getEndLoc - Get the location of the last token of this operand.
1148 SMLoc getEndLoc() const override { return EndLoc; }
1150 virtual ~MipsOperand() {
1158 delete RegList.List;
1159 case k_PhysRegister:
1160 case k_RegisterIndex:
1167 void print(raw_ostream &OS) const override {
1176 Mem.Base->print(OS);
1181 case k_PhysRegister:
1182 OS << "PhysReg<" << PhysReg.Num << ">";
1184 case k_RegisterIndex:
1185 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1192 for (auto Reg : (*RegList.List))
1197 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1201 }; // class MipsOperand
1205 extern const MCInstrDesc MipsInsts[];
1207 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1208 return MipsInsts[Opcode];
1211 static bool hasShortDelaySlot(unsigned Opcode) {
1214 case Mips::JALRS_MM:
1215 case Mips::JALRS16_MM:
1216 case Mips::BGEZALS_MM:
1217 case Mips::BLTZALS_MM:
1224 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1225 SmallVectorImpl<MCInst> &Instructions) {
1226 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1230 if (MCID.isBranch() || MCID.isCall()) {
1231 const unsigned Opcode = Inst.getOpcode();
1241 assert(hasCnMips() && "instruction only valid for octeon cpus");
1248 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1249 Offset = Inst.getOperand(2);
1250 if (!Offset.isImm())
1251 break; // We'll deal with this situation later on when applying fixups.
1252 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1253 return Error(IDLoc, "branch target out of range");
1254 if (OffsetToAlignment(Offset.getImm(),
1255 1LL << (inMicroMipsMode() ? 1 : 2)))
1256 return Error(IDLoc, "branch to misaligned address");
1270 case Mips::BGEZAL_MM:
1271 case Mips::BLTZAL_MM:
1274 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1275 Offset = Inst.getOperand(1);
1276 if (!Offset.isImm())
1277 break; // We'll deal with this situation later on when applying fixups.
1278 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1279 return Error(IDLoc, "branch target out of range");
1280 if (OffsetToAlignment(Offset.getImm(),
1281 1LL << (inMicroMipsMode() ? 1 : 2)))
1282 return Error(IDLoc, "branch to misaligned address");
1284 case Mips::BEQZ16_MM:
1285 case Mips::BNEZ16_MM:
1286 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1287 Offset = Inst.getOperand(1);
1288 if (!Offset.isImm())
1289 break; // We'll deal with this situation later on when applying fixups.
1290 if (!isIntN(8, Offset.getImm()))
1291 return Error(IDLoc, "branch target out of range");
1292 if (OffsetToAlignment(Offset.getImm(), 2LL))
1293 return Error(IDLoc, "branch to misaligned address");
1298 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1299 // We still accept it but it is a normal nop.
1300 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1301 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1302 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1307 const unsigned Opcode = Inst.getOpcode();
1319 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1320 // The offset is handled above
1321 Opnd = Inst.getOperand(1);
1323 return Error(IDLoc, "expected immediate operand kind");
1324 Imm = Opnd.getImm();
1325 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1326 Opcode == Mips::BBIT1 ? 63 : 31))
1327 return Error(IDLoc, "immediate operand value out of range");
1329 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1331 Inst.getOperand(1).setImm(Imm - 32);
1339 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1341 Opnd = Inst.getOperand(3);
1343 return Error(IDLoc, "expected immediate operand kind");
1344 Imm = Opnd.getImm();
1345 if (Imm < 0 || Imm > 31)
1346 return Error(IDLoc, "immediate operand value out of range");
1348 Opnd = Inst.getOperand(2);
1350 return Error(IDLoc, "expected immediate operand kind");
1351 Imm = Opnd.getImm();
1352 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1353 Opcode == Mips::EXTS ? 63 : 31))
1354 return Error(IDLoc, "immediate operand value out of range");
1356 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1357 Inst.getOperand(2).setImm(Imm - 32);
1363 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1364 Opnd = Inst.getOperand(2);
1366 return Error(IDLoc, "expected immediate operand kind");
1367 Imm = Opnd.getImm();
1368 if (!isInt<10>(Imm))
1369 return Error(IDLoc, "immediate operand value out of range");
1374 // If this instruction has a delay slot and .set reorder is active,
1375 // emit a NOP after it.
1376 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1377 Instructions.push_back(Inst);
1378 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1382 if (MCID.mayLoad() || MCID.mayStore()) {
1383 // Check the offset of memory operand, if it is a symbol
1384 // reference or immediate we may have to expand instructions.
1385 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1386 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1387 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1388 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1389 MCOperand &Op = Inst.getOperand(i);
1391 int MemOffset = Op.getImm();
1392 if (MemOffset < -32768 || MemOffset > 32767) {
1393 // Offset can't exceed 16bit value.
1394 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1397 } else if (Op.isExpr()) {
1398 const MCExpr *Expr = Op.getExpr();
1399 if (Expr->getKind() == MCExpr::SymbolRef) {
1400 const MCSymbolRefExpr *SR =
1401 static_cast<const MCSymbolRefExpr *>(Expr);
1402 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1404 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1407 } else if (!isEvaluated(Expr)) {
1408 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1416 if (inMicroMipsMode()) {
1417 if (MCID.mayLoad()) {
1418 // Try to create 16-bit GP relative load instruction.
1419 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1420 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1421 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1422 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1423 MCOperand &Op = Inst.getOperand(i);
1425 int MemOffset = Op.getImm();
1426 MCOperand &DstReg = Inst.getOperand(0);
1427 MCOperand &BaseReg = Inst.getOperand(1);
1428 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1429 getContext().getRegisterInfo()->getRegClass(
1430 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1431 BaseReg.getReg() == Mips::GP) {
1433 TmpInst.setLoc(IDLoc);
1434 TmpInst.setOpcode(Mips::LWGP_MM);
1435 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1436 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1437 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1438 Instructions.push_back(TmpInst);
1446 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1451 switch (Inst.getOpcode()) {
1454 case Mips::ADDIUS5_MM:
1455 Opnd = Inst.getOperand(2);
1457 return Error(IDLoc, "expected immediate operand kind");
1458 Imm = Opnd.getImm();
1459 if (Imm < -8 || Imm > 7)
1460 return Error(IDLoc, "immediate operand value out of range");
1462 case Mips::ADDIUSP_MM:
1463 Opnd = Inst.getOperand(0);
1465 return Error(IDLoc, "expected immediate operand kind");
1466 Imm = Opnd.getImm();
1467 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1469 return Error(IDLoc, "immediate operand value out of range");
1471 case Mips::SLL16_MM:
1472 case Mips::SRL16_MM:
1473 Opnd = Inst.getOperand(2);
1475 return Error(IDLoc, "expected immediate operand kind");
1476 Imm = Opnd.getImm();
1477 if (Imm < 1 || Imm > 8)
1478 return Error(IDLoc, "immediate operand value out of range");
1481 Opnd = Inst.getOperand(1);
1483 return Error(IDLoc, "expected immediate operand kind");
1484 Imm = Opnd.getImm();
1485 if (Imm < -1 || Imm > 126)
1486 return Error(IDLoc, "immediate operand value out of range");
1488 case Mips::ADDIUR2_MM:
1489 Opnd = Inst.getOperand(2);
1491 return Error(IDLoc, "expected immediate operand kind");
1492 Imm = Opnd.getImm();
1493 if (!(Imm == 1 || Imm == -1 ||
1494 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1495 return Error(IDLoc, "immediate operand value out of range");
1497 case Mips::ADDIUR1SP_MM:
1498 Opnd = Inst.getOperand(1);
1500 return Error(IDLoc, "expected immediate operand kind");
1501 Imm = Opnd.getImm();
1502 if (OffsetToAlignment(Imm, 4LL))
1503 return Error(IDLoc, "misaligned immediate operand value");
1504 if (Imm < 0 || Imm > 255)
1505 return Error(IDLoc, "immediate operand value out of range");
1507 case Mips::ANDI16_MM:
1508 Opnd = Inst.getOperand(2);
1510 return Error(IDLoc, "expected immediate operand kind");
1511 Imm = Opnd.getImm();
1512 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1513 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1514 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1515 return Error(IDLoc, "immediate operand value out of range");
1517 case Mips::LBU16_MM:
1518 Opnd = Inst.getOperand(2);
1520 return Error(IDLoc, "expected immediate operand kind");
1521 Imm = Opnd.getImm();
1522 if (Imm < -1 || Imm > 14)
1523 return Error(IDLoc, "immediate operand value out of range");
1526 Opnd = Inst.getOperand(2);
1528 return Error(IDLoc, "expected immediate operand kind");
1529 Imm = Opnd.getImm();
1530 if (Imm < 0 || Imm > 15)
1531 return Error(IDLoc, "immediate operand value out of range");
1533 case Mips::LHU16_MM:
1535 Opnd = Inst.getOperand(2);
1537 return Error(IDLoc, "expected immediate operand kind");
1538 Imm = Opnd.getImm();
1539 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1540 return Error(IDLoc, "immediate operand value out of range");
1544 Opnd = Inst.getOperand(2);
1546 return Error(IDLoc, "expected immediate operand kind");
1547 Imm = Opnd.getImm();
1548 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1549 return Error(IDLoc, "immediate operand value out of range");
1553 Opnd = Inst.getOperand(2);
1555 return Error(IDLoc, "expected immediate operand kind");
1556 Imm = Opnd.getImm();
1557 if (!isUInt<5>(Imm))
1558 return Error(IDLoc, "immediate operand value out of range");
1560 case Mips::ADDIUPC_MM:
1561 MCOperand Opnd = Inst.getOperand(1);
1563 return Error(IDLoc, "expected immediate operand kind");
1564 int Imm = Opnd.getImm();
1565 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1566 return Error(IDLoc, "immediate operand value out of range");
1571 if (needsExpansion(Inst))
1572 return expandInstruction(Inst, IDLoc, Instructions);
1574 Instructions.push_back(Inst);
1579 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1581 switch (Inst.getOpcode()) {
1582 case Mips::LoadImm32:
1583 case Mips::LoadImm64:
1584 case Mips::LoadAddrImm32:
1585 case Mips::LoadAddrReg32:
1586 case Mips::B_MM_Pseudo:
1589 case Mips::JalOneReg:
1590 case Mips::JalTwoReg:
1597 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1598 SmallVectorImpl<MCInst> &Instructions) {
1599 switch (Inst.getOpcode()) {
1600 default: llvm_unreachable("unimplemented expansion");
1601 case Mips::LoadImm32:
1602 return expandLoadImm(Inst, IDLoc, Instructions);
1603 case Mips::LoadImm64:
1605 Error(IDLoc, "instruction requires a 64-bit architecture");
1608 return expandLoadImm(Inst, IDLoc, Instructions);
1609 case Mips::LoadAddrImm32:
1610 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1611 case Mips::LoadAddrReg32:
1612 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1613 case Mips::B_MM_Pseudo:
1614 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1617 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1618 case Mips::JalOneReg:
1619 case Mips::JalTwoReg:
1620 return expandJalWithRegs(Inst, IDLoc, Instructions);
1625 template <bool PerformShift>
1626 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1627 SmallVectorImpl<MCInst> &Instructions) {
1630 tmpInst.setOpcode(Mips::DSLL);
1631 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1632 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1633 tmpInst.addOperand(MCOperand::CreateImm(16));
1634 tmpInst.setLoc(IDLoc);
1635 Instructions.push_back(tmpInst);
1638 tmpInst.setOpcode(Mips::ORi);
1639 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1640 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1641 tmpInst.addOperand(Operand);
1642 tmpInst.setLoc(IDLoc);
1643 Instructions.push_back(tmpInst);
1646 template <int Shift, bool PerformShift>
1647 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1648 SmallVectorImpl<MCInst> &Instructions) {
1649 createShiftOr<PerformShift>(
1650 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1651 IDLoc, Instructions);
1655 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1656 SmallVectorImpl<MCInst> &Instructions) {
1657 // Create a JALR instruction which is going to replace the pseudo-JAL.
1659 JalrInst.setLoc(IDLoc);
1660 const MCOperand FirstRegOp = Inst.getOperand(0);
1661 const unsigned Opcode = Inst.getOpcode();
1663 if (Opcode == Mips::JalOneReg) {
1664 // jal $rs => jalr $rs
1665 if (inMicroMipsMode()) {
1666 JalrInst.setOpcode(Mips::JALR16_MM);
1667 JalrInst.addOperand(FirstRegOp);
1669 JalrInst.setOpcode(Mips::JALR);
1670 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1671 JalrInst.addOperand(FirstRegOp);
1673 } else if (Opcode == Mips::JalTwoReg) {
1674 // jal $rd, $rs => jalr $rd, $rs
1675 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1676 JalrInst.addOperand(FirstRegOp);
1677 const MCOperand SecondRegOp = Inst.getOperand(1);
1678 JalrInst.addOperand(SecondRegOp);
1680 Instructions.push_back(JalrInst);
1682 // If .set reorder is active, emit a NOP after it.
1683 if (AssemblerOptions.back()->isReorder()) {
1684 // This is a 32-bit NOP because these 2 pseudo-instructions
1685 // do not have a short delay slot.
1687 NopInst.setOpcode(Mips::SLL);
1688 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1689 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1690 NopInst.addOperand(MCOperand::CreateImm(0));
1691 Instructions.push_back(NopInst);
1697 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1698 SmallVectorImpl<MCInst> &Instructions) {
1700 const MCOperand &ImmOp = Inst.getOperand(1);
1701 assert(ImmOp.isImm() && "expected immediate operand kind");
1702 const MCOperand &RegOp = Inst.getOperand(0);
1703 assert(RegOp.isReg() && "expected register operand kind");
1705 int64_t ImmValue = ImmOp.getImm();
1706 tmpInst.setLoc(IDLoc);
1707 // FIXME: gas has a special case for values that are 000...1111, which
1708 // becomes a li -1 and then a dsrl
1709 if (0 <= ImmValue && ImmValue <= 65535) {
1710 // For 0 <= j <= 65535.
1711 // li d,j => ori d,$zero,j
1712 tmpInst.setOpcode(Mips::ORi);
1713 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1714 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1715 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1716 Instructions.push_back(tmpInst);
1717 } else if (ImmValue < 0 && ImmValue >= -32768) {
1718 // For -32768 <= j < 0.
1719 // li d,j => addiu d,$zero,j
1720 tmpInst.setOpcode(Mips::ADDiu);
1721 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1722 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1723 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1724 Instructions.push_back(tmpInst);
1725 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1726 // For any value of j that is representable as a 32-bit integer, create
1728 // li d,j => lui d,hi16(j)
1730 tmpInst.setOpcode(Mips::LUi);
1731 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1732 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1733 Instructions.push_back(tmpInst);
1734 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1735 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1737 Error(IDLoc, "instruction requires a 64-bit architecture");
1741 // <------- lo32 ------>
1742 // <------- hi32 ------>
1743 // <- hi16 -> <- lo16 ->
1744 // _________________________________
1746 // | 16-bytes | 16-bytes | 16-bytes |
1747 // |__________|__________|__________|
1749 // For any value of j that is representable as a 48-bit integer, create
1751 // li d,j => lui d,hi16(j)
1752 // ori d,d,hi16(lo32(j))
1754 // ori d,d,lo16(lo32(j))
1755 tmpInst.setOpcode(Mips::LUi);
1756 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1758 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1759 Instructions.push_back(tmpInst);
1760 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1761 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1764 Error(IDLoc, "instruction requires a 64-bit architecture");
1768 // <------- hi32 ------> <------- lo32 ------>
1769 // <- hi16 -> <- lo16 ->
1770 // ___________________________________________
1772 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1773 // |__________|__________|__________|__________|
1775 // For any value of j that isn't representable as a 48-bit integer.
1776 // li d,j => lui d,hi16(j)
1777 // ori d,d,lo16(hi32(j))
1779 // ori d,d,hi16(lo32(j))
1781 // ori d,d,lo16(lo32(j))
1782 tmpInst.setOpcode(Mips::LUi);
1783 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1785 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1786 Instructions.push_back(tmpInst);
1787 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1788 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1789 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1795 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1796 SmallVectorImpl<MCInst> &Instructions) {
1798 const MCOperand &ImmOp = Inst.getOperand(2);
1799 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1800 "expected immediate operand kind");
1801 if (!ImmOp.isImm()) {
1802 expandLoadAddressSym(Inst, IDLoc, Instructions);
1805 const MCOperand &SrcRegOp = Inst.getOperand(1);
1806 assert(SrcRegOp.isReg() && "expected register operand kind");
1807 const MCOperand &DstRegOp = Inst.getOperand(0);
1808 assert(DstRegOp.isReg() && "expected register operand kind");
1809 int ImmValue = ImmOp.getImm();
1810 if (-32768 <= ImmValue && ImmValue <= 65535) {
1811 // For -32768 <= j <= 65535.
1812 // la d,j(s) => addiu d,s,j
1813 tmpInst.setOpcode(Mips::ADDiu);
1814 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1815 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1816 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1817 Instructions.push_back(tmpInst);
1819 // For any other value of j that is representable as a 32-bit integer.
1820 // la d,j(s) => lui d,hi16(j)
1823 tmpInst.setOpcode(Mips::LUi);
1824 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1825 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1826 Instructions.push_back(tmpInst);
1828 tmpInst.setOpcode(Mips::ORi);
1829 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1830 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1831 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1832 Instructions.push_back(tmpInst);
1834 tmpInst.setOpcode(Mips::ADDu);
1835 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1836 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1837 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1838 Instructions.push_back(tmpInst);
1844 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1845 SmallVectorImpl<MCInst> &Instructions) {
1847 const MCOperand &ImmOp = Inst.getOperand(1);
1848 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1849 "expected immediate operand kind");
1850 if (!ImmOp.isImm()) {
1851 expandLoadAddressSym(Inst, IDLoc, Instructions);
1854 const MCOperand &RegOp = Inst.getOperand(0);
1855 assert(RegOp.isReg() && "expected register operand kind");
1856 int ImmValue = ImmOp.getImm();
1857 if (-32768 <= ImmValue && ImmValue <= 65535) {
1858 // For -32768 <= j <= 65535.
1859 // la d,j => addiu d,$zero,j
1860 tmpInst.setOpcode(Mips::ADDiu);
1861 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1862 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1863 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1864 Instructions.push_back(tmpInst);
1866 // For any other value of j that is representable as a 32-bit integer.
1867 // la d,j => lui d,hi16(j)
1869 tmpInst.setOpcode(Mips::LUi);
1870 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1871 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1872 Instructions.push_back(tmpInst);
1874 tmpInst.setOpcode(Mips::ORi);
1875 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1876 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1877 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1878 Instructions.push_back(tmpInst);
1884 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1885 SmallVectorImpl<MCInst> &Instructions) {
1886 // FIXME: If we do have a valid at register to use, we should generate a
1887 // slightly shorter sequence here.
1889 int ExprOperandNo = 1;
1890 // Sometimes the assembly parser will get the immediate expression as
1891 // a $zero + an immediate.
1892 if (Inst.getNumOperands() == 3) {
1893 assert(Inst.getOperand(1).getReg() ==
1894 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1897 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1898 assert(SymOp.isExpr() && "expected symbol operand kind");
1899 const MCOperand &RegOp = Inst.getOperand(0);
1900 unsigned RegNo = RegOp.getReg();
1901 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1902 const MCSymbolRefExpr *HiExpr =
1903 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1904 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1905 const MCSymbolRefExpr *LoExpr =
1906 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1907 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1909 // If it's a 64-bit architecture, expand to:
1910 // la d,sym => lui d,highest(sym)
1911 // ori d,d,higher(sym)
1913 // ori d,d,hi16(sym)
1915 // ori d,d,lo16(sym)
1916 const MCSymbolRefExpr *HighestExpr =
1917 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1918 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1919 const MCSymbolRefExpr *HigherExpr =
1920 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1921 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1923 tmpInst.setOpcode(Mips::LUi);
1924 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1925 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1926 Instructions.push_back(tmpInst);
1928 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1930 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1932 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1935 // Otherwise, expand to:
1936 // la d,sym => lui d,hi16(sym)
1937 // ori d,d,lo16(sym)
1938 tmpInst.setOpcode(Mips::LUi);
1939 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1940 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1941 Instructions.push_back(tmpInst);
1943 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1948 bool MipsAsmParser::expandUncondBranchMMPseudo(
1949 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1950 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1951 "unexpected number of operands");
1953 MCOperand Offset = Inst.getOperand(0);
1954 if (Offset.isExpr()) {
1956 Inst.setOpcode(Mips::BEQ_MM);
1957 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1958 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1959 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1961 assert(Offset.isImm() && "expected immediate operand kind");
1962 if (isIntN(11, Offset.getImm())) {
1963 // If offset fits into 11 bits then this instruction becomes microMIPS
1964 // 16-bit unconditional branch instruction.
1965 Inst.setOpcode(Mips::B16_MM);
1967 if (!isIntN(17, Offset.getImm()))
1968 Error(IDLoc, "branch target out of range");
1969 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1970 Error(IDLoc, "branch to misaligned address");
1972 Inst.setOpcode(Mips::BEQ_MM);
1973 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1974 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1975 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1978 Instructions.push_back(Inst);
1980 // If .set reorder is active, emit a NOP after the branch instruction.
1981 if (AssemblerOptions.back()->isReorder())
1982 createNop(true, IDLoc, Instructions);
1987 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1988 SmallVectorImpl<MCInst> &Instructions,
1989 bool isLoad, bool isImmOpnd) {
1990 const MCSymbolRefExpr *SR;
1992 unsigned ImmOffset, HiOffset, LoOffset;
1993 const MCExpr *ExprOffset;
1995 // 1st operand is either the source or destination register.
1996 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1997 unsigned RegOpNum = Inst.getOperand(0).getReg();
1998 // 2nd operand is the base register.
1999 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2000 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2001 // 3rd operand is either an immediate or expression.
2003 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2004 ImmOffset = Inst.getOperand(2).getImm();
2005 LoOffset = ImmOffset & 0x0000ffff;
2006 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2007 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2008 if (LoOffset & 0x8000)
2011 ExprOffset = Inst.getOperand(2).getExpr();
2012 // All instructions will have the same location.
2013 TempInst.setLoc(IDLoc);
2014 // These are some of the types of expansions we perform here:
2015 // 1) lw $8, sym => lui $8, %hi(sym)
2016 // lw $8, %lo(sym)($8)
2017 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2019 // lw $8, %lo(offset)($9)
2020 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2022 // lw $8, %lo(offset)($at)
2023 // 4) sw $8, sym => lui $at, %hi(sym)
2024 // sw $8, %lo(sym)($at)
2025 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2027 // sw $8, %lo(offset)($at)
2028 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2029 // ldc1 $f0, %lo(sym)($at)
2031 // For load instructions we can use the destination register as a temporary
2032 // if base and dst are different (examples 1 and 2) and if the base register
2033 // is general purpose otherwise we must use $at (example 6) and error if it's
2034 // not available. For stores we must use $at (examples 4 and 5) because we
2035 // must not clobber the source register setting up the offset.
2036 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2037 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2038 unsigned RegClassIDOp0 =
2039 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2040 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2041 (RegClassIDOp0 == Mips::GPR64RegClassID);
2042 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2043 TmpRegNum = RegOpNum;
2045 int AT = getATReg(IDLoc);
2046 // At this point we need AT to perform the expansions and we exit if it is
2051 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
2054 TempInst.setOpcode(Mips::LUi);
2055 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2057 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2059 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2060 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2061 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2062 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2064 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2066 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2067 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2070 // Add the instruction to the list.
2071 Instructions.push_back(TempInst);
2072 // Prepare TempInst for next instruction.
2074 // Add temp register to base.
2075 TempInst.setOpcode(Mips::ADDu);
2076 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2077 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2078 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2079 Instructions.push_back(TempInst);
2081 // And finally, create original instruction with low part
2082 // of offset and new base.
2083 TempInst.setOpcode(Inst.getOpcode());
2084 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2085 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2087 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2089 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2090 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2091 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2093 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2095 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2096 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2099 Instructions.push_back(TempInst);
2104 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2105 SmallVectorImpl<MCInst> &Instructions) {
2106 unsigned OpNum = Inst.getNumOperands();
2107 unsigned Opcode = Inst.getOpcode();
2108 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2110 assert (Inst.getOperand(OpNum - 1).isImm() &&
2111 Inst.getOperand(OpNum - 2).isReg() &&
2112 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2114 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2115 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2116 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2117 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2118 // It can be implemented as SWM16 or LWM16 instruction.
2119 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2121 Inst.setOpcode(NewOpcode);
2122 Instructions.push_back(Inst);
2126 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2127 SmallVectorImpl<MCInst> &Instructions) {
2129 if (hasShortDelaySlot) {
2130 NopInst.setOpcode(Mips::MOVE16_MM);
2131 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2132 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2134 NopInst.setOpcode(Mips::SLL);
2135 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2136 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2137 NopInst.addOperand(MCOperand::CreateImm(0));
2139 Instructions.push_back(NopInst);
2142 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2143 // As described by the Mips32r2 spec, the registers Rd and Rs for
2144 // jalr.hb must be different.
2145 unsigned Opcode = Inst.getOpcode();
2147 if (Opcode == Mips::JALR_HB &&
2148 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2149 return Match_RequiresDifferentSrcAndDst;
2151 return Match_Success;
2154 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2155 OperandVector &Operands,
2157 uint64_t &ErrorInfo,
2158 bool MatchingInlineAsm) {
2161 SmallVector<MCInst, 8> Instructions;
2162 unsigned MatchResult =
2163 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2165 switch (MatchResult) {
2166 case Match_Success: {
2167 if (processInstruction(Inst, IDLoc, Instructions))
2169 for (unsigned i = 0; i < Instructions.size(); i++)
2170 Out.EmitInstruction(Instructions[i], STI);
2173 case Match_MissingFeature:
2174 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2176 case Match_InvalidOperand: {
2177 SMLoc ErrorLoc = IDLoc;
2178 if (ErrorInfo != ~0ULL) {
2179 if (ErrorInfo >= Operands.size())
2180 return Error(IDLoc, "too few operands for instruction");
2182 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2183 if (ErrorLoc == SMLoc())
2187 return Error(ErrorLoc, "invalid operand for instruction");
2189 case Match_MnemonicFail:
2190 return Error(IDLoc, "invalid instruction");
2191 case Match_RequiresDifferentSrcAndDst:
2192 return Error(IDLoc, "source and destination must be different");
2195 llvm_unreachable("Implement any new match types added!");
2198 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
2199 if ((RegIndex != 0) &&
2200 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
2202 Warning(Loc, "used $at without \".set noat\"");
2204 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
2205 Twine(RegIndex) + "\"");
2210 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2211 SMRange Range, bool ShowColors) {
2212 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2213 Range, SMFixIt(Range, FixMsg),
2217 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2220 CC = StringSwitch<unsigned>(Name)
2256 if (!(isABI_N32() || isABI_N64()))
2259 if (12 <= CC && CC <= 15) {
2260 // Name is one of t4-t7
2261 AsmToken RegTok = getLexer().peekTok();
2262 SMRange RegRange = RegTok.getLocRange();
2264 StringRef FixedName = StringSwitch<StringRef>(Name)
2270 assert(FixedName != "" && "Register name is not one of t4-t7.");
2272 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2273 "Did you mean $" + FixedName + "?", RegRange);
2276 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2277 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2278 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2279 if (8 <= CC && CC <= 11)
2283 CC = StringSwitch<unsigned>(Name)
2295 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2298 CC = StringSwitch<unsigned>(Name)
2299 .Case("hwr_cpunum", 0)
2300 .Case("hwr_synci_step", 1)
2302 .Case("hwr_ccres", 3)
2303 .Case("hwr_ulr", 29)
2309 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2311 if (Name[0] == 'f') {
2312 StringRef NumString = Name.substr(1);
2314 if (NumString.getAsInteger(10, IntVal))
2315 return -1; // This is not an integer.
2316 if (IntVal > 31) // Maximum index for fpu register.
2323 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2325 if (Name.startswith("fcc")) {
2326 StringRef NumString = Name.substr(3);
2328 if (NumString.getAsInteger(10, IntVal))
2329 return -1; // This is not an integer.
2330 if (IntVal > 7) // There are only 8 fcc registers.
2337 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2339 if (Name.startswith("ac")) {
2340 StringRef NumString = Name.substr(2);
2342 if (NumString.getAsInteger(10, IntVal))
2343 return -1; // This is not an integer.
2344 if (IntVal > 3) // There are only 3 acc registers.
2351 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2354 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2363 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2366 CC = StringSwitch<unsigned>(Name)
2369 .Case("msaaccess", 2)
2371 .Case("msamodify", 4)
2372 .Case("msarequest", 5)
2374 .Case("msaunmap", 7)
2380 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2388 int MipsAsmParser::getATReg(SMLoc Loc) {
2389 int AT = AssemblerOptions.back()->getATRegNum();
2391 reportParseError(Loc,
2392 "pseudo-instruction requires $at, which is not available");
2396 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2397 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2400 unsigned MipsAsmParser::getGPR(int RegNo) {
2401 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2405 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2407 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2410 return getReg(RegClass, RegNum);
2413 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2414 MCAsmParser &Parser = getParser();
2415 DEBUG(dbgs() << "parseOperand\n");
2417 // Check if the current operand has a custom associated parser, if so, try to
2418 // custom parse the operand, or fallback to the general approach.
2419 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2420 if (ResTy == MatchOperand_Success)
2422 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2423 // there was a match, but an error occurred, in which case, just return that
2424 // the operand parsing failed.
2425 if (ResTy == MatchOperand_ParseFail)
2428 DEBUG(dbgs() << ".. Generic Parser\n");
2430 switch (getLexer().getKind()) {
2432 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2434 case AsmToken::Dollar: {
2435 // Parse the register.
2436 SMLoc S = Parser.getTok().getLoc();
2438 // Almost all registers have been parsed by custom parsers. There is only
2439 // one exception to this. $zero (and it's alias $0) will reach this point
2440 // for div, divu, and similar instructions because it is not an operand
2441 // to the instruction definition but an explicit register. Special case
2442 // this situation for now.
2443 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2446 // Maybe it is a symbol reference.
2447 StringRef Identifier;
2448 if (Parser.parseIdentifier(Identifier))
2451 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2452 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2453 // Otherwise create a symbol reference.
2455 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2457 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2460 // Else drop to expression parsing.
2461 case AsmToken::LParen:
2462 case AsmToken::Minus:
2463 case AsmToken::Plus:
2464 case AsmToken::Integer:
2465 case AsmToken::Tilde:
2466 case AsmToken::String: {
2467 DEBUG(dbgs() << ".. generic integer\n");
2468 OperandMatchResultTy ResTy = parseImm(Operands);
2469 return ResTy != MatchOperand_Success;
2471 case AsmToken::Percent: {
2472 // It is a symbol reference or constant expression.
2473 const MCExpr *IdVal;
2474 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2475 if (parseRelocOperand(IdVal))
2478 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2480 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2482 } // case AsmToken::Percent
2483 } // switch(getLexer().getKind())
2487 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2488 StringRef RelocStr) {
2490 // Check the type of the expression.
2491 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2492 // It's a constant, evaluate reloc value.
2494 switch (getVariantKind(RelocStr)) {
2495 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2496 // Get the 1st 16-bits.
2497 Val = MCE->getValue() & 0xffff;
2499 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2500 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2501 // 16 bits being negative.
2502 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2504 case MCSymbolRefExpr::VK_Mips_HIGHER:
2505 // Get the 3rd 16-bits.
2506 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2508 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2509 // Get the 4th 16-bits.
2510 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2513 report_fatal_error("unsupported reloc value");
2515 return MCConstantExpr::Create(Val, getContext());
2518 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2519 // It's a symbol, create a symbolic expression from the symbol.
2520 StringRef Symbol = MSRE->getSymbol().getName();
2521 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2522 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2526 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2527 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2529 // Try to create target expression.
2530 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2531 return MipsMCExpr::Create(VK, Expr, getContext());
2533 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2534 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2535 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2539 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2540 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2541 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2544 // Just return the original expression.
2548 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2550 switch (Expr->getKind()) {
2551 case MCExpr::Constant:
2553 case MCExpr::SymbolRef:
2554 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2555 case MCExpr::Binary:
2556 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2557 if (!isEvaluated(BE->getLHS()))
2559 return isEvaluated(BE->getRHS());
2562 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2563 case MCExpr::Target:
2569 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2570 MCAsmParser &Parser = getParser();
2571 Parser.Lex(); // Eat the % token.
2572 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2573 if (Tok.isNot(AsmToken::Identifier))
2576 std::string Str = Tok.getIdentifier().str();
2578 Parser.Lex(); // Eat the identifier.
2579 // Now make an expression from the rest of the operand.
2580 const MCExpr *IdVal;
2583 if (getLexer().getKind() == AsmToken::LParen) {
2585 Parser.Lex(); // Eat the '(' token.
2586 if (getLexer().getKind() == AsmToken::Percent) {
2587 Parser.Lex(); // Eat the % token.
2588 const AsmToken &nextTok = Parser.getTok();
2589 if (nextTok.isNot(AsmToken::Identifier))
2592 Str += nextTok.getIdentifier();
2593 Parser.Lex(); // Eat the identifier.
2594 if (getLexer().getKind() != AsmToken::LParen)
2599 if (getParser().parseParenExpression(IdVal, EndLoc))
2602 while (getLexer().getKind() == AsmToken::RParen)
2603 Parser.Lex(); // Eat the ')' token.
2606 return true; // Parenthesis must follow the relocation operand.
2608 Res = evaluateRelocExpr(IdVal, Str);
2612 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2614 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2615 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2616 if (ResTy == MatchOperand_Success) {
2617 assert(Operands.size() == 1);
2618 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2619 StartLoc = Operand.getStartLoc();
2620 EndLoc = Operand.getEndLoc();
2622 // AFAIK, we only support numeric registers and named GPR's in CFI
2624 // Don't worry about eating tokens before failing. Using an unrecognised
2625 // register is a parse error.
2626 if (Operand.isGPRAsmReg()) {
2627 // Resolve to GPR32 or GPR64 appropriately.
2628 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2631 return (RegNo == (unsigned)-1);
2634 assert(Operands.size() == 0);
2635 return (RegNo == (unsigned)-1);
2638 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2639 MCAsmParser &Parser = getParser();
2643 while (getLexer().getKind() == AsmToken::LParen)
2646 switch (getLexer().getKind()) {
2649 case AsmToken::Identifier:
2650 case AsmToken::LParen:
2651 case AsmToken::Integer:
2652 case AsmToken::Minus:
2653 case AsmToken::Plus:
2655 Result = getParser().parseParenExpression(Res, S);
2657 Result = (getParser().parseExpression(Res));
2658 while (getLexer().getKind() == AsmToken::RParen)
2661 case AsmToken::Percent:
2662 Result = parseRelocOperand(Res);
2667 MipsAsmParser::OperandMatchResultTy
2668 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2669 MCAsmParser &Parser = getParser();
2670 DEBUG(dbgs() << "parseMemOperand\n");
2671 const MCExpr *IdVal = nullptr;
2673 bool isParenExpr = false;
2674 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2675 // First operand is the offset.
2676 S = Parser.getTok().getLoc();
2678 if (getLexer().getKind() == AsmToken::LParen) {
2683 if (getLexer().getKind() != AsmToken::Dollar) {
2684 if (parseMemOffset(IdVal, isParenExpr))
2685 return MatchOperand_ParseFail;
2687 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2688 if (Tok.isNot(AsmToken::LParen)) {
2689 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2690 if (Mnemonic.getToken() == "la") {
2692 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2693 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2694 return MatchOperand_Success;
2696 if (Tok.is(AsmToken::EndOfStatement)) {
2698 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2700 // Zero register assumed, add a memory operand with ZERO as its base.
2701 // "Base" will be managed by k_Memory.
2702 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2705 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2706 return MatchOperand_Success;
2708 Error(Parser.getTok().getLoc(), "'(' expected");
2709 return MatchOperand_ParseFail;
2712 Parser.Lex(); // Eat the '(' token.
2715 Res = parseAnyRegister(Operands);
2716 if (Res != MatchOperand_Success)
2719 if (Parser.getTok().isNot(AsmToken::RParen)) {
2720 Error(Parser.getTok().getLoc(), "')' expected");
2721 return MatchOperand_ParseFail;
2724 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2726 Parser.Lex(); // Eat the ')' token.
2729 IdVal = MCConstantExpr::Create(0, getContext());
2731 // Replace the register operand with the memory operand.
2732 std::unique_ptr<MipsOperand> op(
2733 static_cast<MipsOperand *>(Operands.back().release()));
2734 // Remove the register from the operands.
2735 // "op" will be managed by k_Memory.
2736 Operands.pop_back();
2737 // Add the memory operand.
2738 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2740 if (IdVal->EvaluateAsAbsolute(Imm))
2741 IdVal = MCConstantExpr::Create(Imm, getContext());
2742 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2743 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2747 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2748 return MatchOperand_Success;
2751 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2752 MCAsmParser &Parser = getParser();
2753 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2755 SMLoc S = Parser.getTok().getLoc();
2757 if (Sym->isVariable())
2758 Expr = Sym->getVariableValue();
2761 if (Expr->getKind() == MCExpr::SymbolRef) {
2762 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2763 StringRef DefSymbol = Ref->getSymbol().getName();
2764 if (DefSymbol.startswith("$")) {
2765 OperandMatchResultTy ResTy =
2766 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2767 if (ResTy == MatchOperand_Success) {
2770 } else if (ResTy == MatchOperand_ParseFail)
2771 llvm_unreachable("Should never ParseFail");
2774 } else if (Expr->getKind() == MCExpr::Constant) {
2776 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2778 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2785 MipsAsmParser::OperandMatchResultTy
2786 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2787 StringRef Identifier,
2789 int Index = matchCPURegisterName(Identifier);
2791 Operands.push_back(MipsOperand::createGPRReg(
2792 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2793 return MatchOperand_Success;
2796 Index = matchHWRegsRegisterName(Identifier);
2798 Operands.push_back(MipsOperand::createHWRegsReg(
2799 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2800 return MatchOperand_Success;
2803 Index = matchFPURegisterName(Identifier);
2805 Operands.push_back(MipsOperand::createFGRReg(
2806 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2807 return MatchOperand_Success;
2810 Index = matchFCCRegisterName(Identifier);
2812 Operands.push_back(MipsOperand::createFCCReg(
2813 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2814 return MatchOperand_Success;
2817 Index = matchACRegisterName(Identifier);
2819 Operands.push_back(MipsOperand::createACCReg(
2820 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2821 return MatchOperand_Success;
2824 Index = matchMSA128RegisterName(Identifier);
2826 Operands.push_back(MipsOperand::createMSA128Reg(
2827 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2828 return MatchOperand_Success;
2831 Index = matchMSA128CtrlRegisterName(Identifier);
2833 Operands.push_back(MipsOperand::createMSACtrlReg(
2834 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2835 return MatchOperand_Success;
2838 return MatchOperand_NoMatch;
2841 MipsAsmParser::OperandMatchResultTy
2842 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2843 MCAsmParser &Parser = getParser();
2844 auto Token = Parser.getLexer().peekTok(false);
2846 if (Token.is(AsmToken::Identifier)) {
2847 DEBUG(dbgs() << ".. identifier\n");
2848 StringRef Identifier = Token.getIdentifier();
2849 OperandMatchResultTy ResTy =
2850 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2852 } else if (Token.is(AsmToken::Integer)) {
2853 DEBUG(dbgs() << ".. integer\n");
2854 Operands.push_back(MipsOperand::createNumericReg(
2855 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2857 return MatchOperand_Success;
2860 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2862 return MatchOperand_NoMatch;
2865 MipsAsmParser::OperandMatchResultTy
2866 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2867 MCAsmParser &Parser = getParser();
2868 DEBUG(dbgs() << "parseAnyRegister\n");
2870 auto Token = Parser.getTok();
2872 SMLoc S = Token.getLoc();
2874 if (Token.isNot(AsmToken::Dollar)) {
2875 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2876 if (Token.is(AsmToken::Identifier)) {
2877 if (searchSymbolAlias(Operands))
2878 return MatchOperand_Success;
2880 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2881 return MatchOperand_NoMatch;
2883 DEBUG(dbgs() << ".. $\n");
2885 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2886 if (ResTy == MatchOperand_Success) {
2888 Parser.Lex(); // identifier
2893 MipsAsmParser::OperandMatchResultTy
2894 MipsAsmParser::parseImm(OperandVector &Operands) {
2895 MCAsmParser &Parser = getParser();
2896 switch (getLexer().getKind()) {
2898 return MatchOperand_NoMatch;
2899 case AsmToken::LParen:
2900 case AsmToken::Minus:
2901 case AsmToken::Plus:
2902 case AsmToken::Integer:
2903 case AsmToken::Tilde:
2904 case AsmToken::String:
2908 const MCExpr *IdVal;
2909 SMLoc S = Parser.getTok().getLoc();
2910 if (getParser().parseExpression(IdVal))
2911 return MatchOperand_ParseFail;
2913 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2914 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2915 return MatchOperand_Success;
2918 MipsAsmParser::OperandMatchResultTy
2919 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2920 MCAsmParser &Parser = getParser();
2921 DEBUG(dbgs() << "parseJumpTarget\n");
2923 SMLoc S = getLexer().getLoc();
2925 // Integers and expressions are acceptable
2926 OperandMatchResultTy ResTy = parseImm(Operands);
2927 if (ResTy != MatchOperand_NoMatch)
2930 // Registers are a valid target and have priority over symbols.
2931 ResTy = parseAnyRegister(Operands);
2932 if (ResTy != MatchOperand_NoMatch)
2935 const MCExpr *Expr = nullptr;
2936 if (Parser.parseExpression(Expr)) {
2937 // We have no way of knowing if a symbol was consumed so we must ParseFail
2938 return MatchOperand_ParseFail;
2941 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2942 return MatchOperand_Success;
2945 MipsAsmParser::OperandMatchResultTy
2946 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2947 MCAsmParser &Parser = getParser();
2948 const MCExpr *IdVal;
2949 // If the first token is '$' we may have register operand.
2950 if (Parser.getTok().is(AsmToken::Dollar))
2951 return MatchOperand_NoMatch;
2952 SMLoc S = Parser.getTok().getLoc();
2953 if (getParser().parseExpression(IdVal))
2954 return MatchOperand_ParseFail;
2955 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2956 assert(MCE && "Unexpected MCExpr type.");
2957 int64_t Val = MCE->getValue();
2958 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2959 Operands.push_back(MipsOperand::CreateImm(
2960 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2961 return MatchOperand_Success;
2964 MipsAsmParser::OperandMatchResultTy
2965 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2966 MCAsmParser &Parser = getParser();
2967 switch (getLexer().getKind()) {
2969 return MatchOperand_NoMatch;
2970 case AsmToken::LParen:
2971 case AsmToken::Plus:
2972 case AsmToken::Minus:
2973 case AsmToken::Integer:
2978 SMLoc S = Parser.getTok().getLoc();
2980 if (getParser().parseExpression(Expr))
2981 return MatchOperand_ParseFail;
2984 if (!Expr->EvaluateAsAbsolute(Val)) {
2985 Error(S, "expected immediate value");
2986 return MatchOperand_ParseFail;
2989 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2990 // and because the CPU always adds one to the immediate field, the allowed
2991 // range becomes 1..4. We'll only check the range here and will deal
2992 // with the addition/subtraction when actually decoding/encoding
2994 if (Val < 1 || Val > 4) {
2995 Error(S, "immediate not in range (1..4)");
2996 return MatchOperand_ParseFail;
3000 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3001 return MatchOperand_Success;
3004 MipsAsmParser::OperandMatchResultTy
3005 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3006 MCAsmParser &Parser = getParser();
3007 SmallVector<unsigned, 10> Regs;
3009 unsigned PrevReg = Mips::NoRegister;
3010 bool RegRange = false;
3011 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3013 if (Parser.getTok().isNot(AsmToken::Dollar))
3014 return MatchOperand_ParseFail;
3016 SMLoc S = Parser.getTok().getLoc();
3017 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3018 SMLoc E = getLexer().getLoc();
3019 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3020 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3022 // Remove last register operand because registers from register range
3023 // should be inserted first.
3024 if (RegNo == Mips::RA) {
3025 Regs.push_back(RegNo);
3027 unsigned TmpReg = PrevReg + 1;
3028 while (TmpReg <= RegNo) {
3029 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3030 Error(E, "invalid register operand");
3031 return MatchOperand_ParseFail;
3035 Regs.push_back(TmpReg++);
3041 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3042 (RegNo != Mips::RA)) {
3043 Error(E, "$16 or $31 expected");
3044 return MatchOperand_ParseFail;
3045 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3046 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3047 Error(E, "invalid register operand");
3048 return MatchOperand_ParseFail;
3049 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3050 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3051 Error(E, "consecutive register numbers expected");
3052 return MatchOperand_ParseFail;
3055 Regs.push_back(RegNo);
3058 if (Parser.getTok().is(AsmToken::Minus))
3061 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3062 !Parser.getTok().isNot(AsmToken::Comma)) {
3063 Error(E, "',' or '-' expected");
3064 return MatchOperand_ParseFail;
3067 Lex(); // Consume comma or minus
3068 if (Parser.getTok().isNot(AsmToken::Dollar))
3074 SMLoc E = Parser.getTok().getLoc();
3075 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3076 parseMemOperand(Operands);
3077 return MatchOperand_Success;
3080 MipsAsmParser::OperandMatchResultTy
3081 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3082 MCAsmParser &Parser = getParser();
3084 SMLoc S = Parser.getTok().getLoc();
3085 if (parseAnyRegister(Operands) != MatchOperand_Success)
3086 return MatchOperand_ParseFail;
3088 SMLoc E = Parser.getTok().getLoc();
3089 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3090 unsigned Reg = Op.getGPR32Reg();
3091 Operands.pop_back();
3092 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3093 return MatchOperand_Success;
3096 MipsAsmParser::OperandMatchResultTy
3097 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3098 MCAsmParser &Parser = getParser();
3099 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3100 SmallVector<unsigned, 10> Regs;
3102 if (Parser.getTok().isNot(AsmToken::Dollar))
3103 return MatchOperand_ParseFail;
3105 SMLoc S = Parser.getTok().getLoc();
3107 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3108 return MatchOperand_ParseFail;
3110 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3111 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3112 Regs.push_back(RegNo);
3114 SMLoc E = Parser.getTok().getLoc();
3115 if (Parser.getTok().isNot(AsmToken::Comma)) {
3116 Error(E, "',' expected");
3117 return MatchOperand_ParseFail;
3123 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3124 return MatchOperand_ParseFail;
3126 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3127 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3128 Regs.push_back(RegNo);
3130 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3132 return MatchOperand_Success;
3135 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3137 MCSymbolRefExpr::VariantKind VK =
3138 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3139 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3140 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3141 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3142 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3143 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3144 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3145 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3146 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3147 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3148 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3149 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3150 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3151 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3152 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3153 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3154 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3155 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3156 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3157 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3158 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3159 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3160 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3161 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3162 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3163 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3164 .Default(MCSymbolRefExpr::VK_None);
3166 assert(VK != MCSymbolRefExpr::VK_None);
3171 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3173 /// ::= '(', register, ')'
3174 /// handle it before we iterate so we don't get tripped up by the lack of
3176 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3177 MCAsmParser &Parser = getParser();
3178 if (getLexer().is(AsmToken::LParen)) {
3180 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3182 if (parseOperand(Operands, Name)) {
3183 SMLoc Loc = getLexer().getLoc();
3184 Parser.eatToEndOfStatement();
3185 return Error(Loc, "unexpected token in argument list");
3187 if (Parser.getTok().isNot(AsmToken::RParen)) {
3188 SMLoc Loc = getLexer().getLoc();
3189 Parser.eatToEndOfStatement();
3190 return Error(Loc, "unexpected token, expected ')'");
3193 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3199 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3200 /// either one of these.
3201 /// ::= '[', register, ']'
3202 /// ::= '[', integer, ']'
3203 /// handle it before we iterate so we don't get tripped up by the lack of
3205 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3206 OperandVector &Operands) {
3207 MCAsmParser &Parser = getParser();
3208 if (getLexer().is(AsmToken::LBrac)) {
3210 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3212 if (parseOperand(Operands, Name)) {
3213 SMLoc Loc = getLexer().getLoc();
3214 Parser.eatToEndOfStatement();
3215 return Error(Loc, "unexpected token in argument list");
3217 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3218 SMLoc Loc = getLexer().getLoc();
3219 Parser.eatToEndOfStatement();
3220 return Error(Loc, "unexpected token, expected ']'");
3223 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3229 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3230 SMLoc NameLoc, OperandVector &Operands) {
3231 MCAsmParser &Parser = getParser();
3232 DEBUG(dbgs() << "ParseInstruction\n");
3234 // We have reached first instruction, module directive are now forbidden.
3235 getTargetStreamer().forbidModuleDirective();
3237 // Check if we have valid mnemonic
3238 if (!mnemonicIsValid(Name, 0)) {
3239 Parser.eatToEndOfStatement();
3240 return Error(NameLoc, "unknown instruction");
3242 // First operand in MCInst is instruction mnemonic.
3243 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3245 // Read the remaining operands.
3246 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3247 // Read the first operand.
3248 if (parseOperand(Operands, Name)) {
3249 SMLoc Loc = getLexer().getLoc();
3250 Parser.eatToEndOfStatement();
3251 return Error(Loc, "unexpected token in argument list");
3253 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3255 // AFAIK, parenthesis suffixes are never on the first operand
3257 while (getLexer().is(AsmToken::Comma)) {
3258 Parser.Lex(); // Eat the comma.
3259 // Parse and remember the operand.
3260 if (parseOperand(Operands, Name)) {
3261 SMLoc Loc = getLexer().getLoc();
3262 Parser.eatToEndOfStatement();
3263 return Error(Loc, "unexpected token in argument list");
3265 // Parse bracket and parenthesis suffixes before we iterate
3266 if (getLexer().is(AsmToken::LBrac)) {
3267 if (parseBracketSuffix(Name, Operands))
3269 } else if (getLexer().is(AsmToken::LParen) &&
3270 parseParenSuffix(Name, Operands))
3274 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3275 SMLoc Loc = getLexer().getLoc();
3276 Parser.eatToEndOfStatement();
3277 return Error(Loc, "unexpected token in argument list");
3279 Parser.Lex(); // Consume the EndOfStatement.
3283 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3284 MCAsmParser &Parser = getParser();
3285 SMLoc Loc = getLexer().getLoc();
3286 Parser.eatToEndOfStatement();
3287 return Error(Loc, ErrorMsg);
3290 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3291 return Error(Loc, ErrorMsg);
3294 bool MipsAsmParser::parseSetNoAtDirective() {
3295 MCAsmParser &Parser = getParser();
3296 // Line should look like: ".set noat".
3298 // Set the $at register to $0.
3299 AssemblerOptions.back()->setATReg(0);
3301 Parser.Lex(); // Eat "noat".
3303 // If this is not the end of the statement, report an error.
3304 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3305 reportParseError("unexpected token, expected end of statement");
3309 getTargetStreamer().emitDirectiveSetNoAt();
3310 Parser.Lex(); // Consume the EndOfStatement.
3314 bool MipsAsmParser::parseSetAtDirective() {
3315 // Line can be: ".set at", which sets $at to $1
3316 // or ".set at=$reg", which sets $at to $reg.
3317 MCAsmParser &Parser = getParser();
3318 Parser.Lex(); // Eat "at".
3320 if (getLexer().is(AsmToken::EndOfStatement)) {
3321 // No register was specified, so we set $at to $1.
3322 AssemblerOptions.back()->setATReg(1);
3324 getTargetStreamer().emitDirectiveSetAt();
3325 Parser.Lex(); // Consume the EndOfStatement.
3329 if (getLexer().isNot(AsmToken::Equal)) {
3330 reportParseError("unexpected token, expected equals sign");
3333 Parser.Lex(); // Eat "=".
3335 if (getLexer().isNot(AsmToken::Dollar)) {
3336 if (getLexer().is(AsmToken::EndOfStatement)) {
3337 reportParseError("no register specified");
3340 reportParseError("unexpected token, expected dollar sign '$'");
3344 Parser.Lex(); // Eat "$".
3346 // Find out what "reg" is.
3348 const AsmToken &Reg = Parser.getTok();
3349 if (Reg.is(AsmToken::Identifier)) {
3350 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3351 } else if (Reg.is(AsmToken::Integer)) {
3352 AtRegNo = Reg.getIntVal();
3354 reportParseError("unexpected token, expected identifier or integer");
3358 // Check if $reg is a valid register. If it is, set $at to $reg.
3359 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3360 reportParseError("invalid register");
3363 Parser.Lex(); // Eat "reg".
3365 // If this is not the end of the statement, report an error.
3366 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3367 reportParseError("unexpected token, expected end of statement");
3371 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3373 Parser.Lex(); // Consume the EndOfStatement.
3377 bool MipsAsmParser::parseSetReorderDirective() {
3378 MCAsmParser &Parser = getParser();
3380 // If this is not the end of the statement, report an error.
3381 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3382 reportParseError("unexpected token, expected end of statement");
3385 AssemblerOptions.back()->setReorder();
3386 getTargetStreamer().emitDirectiveSetReorder();
3387 Parser.Lex(); // Consume the EndOfStatement.
3391 bool MipsAsmParser::parseSetNoReorderDirective() {
3392 MCAsmParser &Parser = getParser();
3394 // If this is not the end of the statement, report an error.
3395 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3396 reportParseError("unexpected token, expected end of statement");
3399 AssemblerOptions.back()->setNoReorder();
3400 getTargetStreamer().emitDirectiveSetNoReorder();
3401 Parser.Lex(); // Consume the EndOfStatement.
3405 bool MipsAsmParser::parseSetMacroDirective() {
3406 MCAsmParser &Parser = getParser();
3408 // If this is not the end of the statement, report an error.
3409 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3410 reportParseError("unexpected token, expected end of statement");
3413 AssemblerOptions.back()->setMacro();
3414 Parser.Lex(); // Consume the EndOfStatement.
3418 bool MipsAsmParser::parseSetNoMacroDirective() {
3419 MCAsmParser &Parser = getParser();
3421 // If this is not the end of the statement, report an error.
3422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3423 reportParseError("unexpected token, expected end of statement");
3426 if (AssemblerOptions.back()->isReorder()) {
3427 reportParseError("`noreorder' must be set before `nomacro'");
3430 AssemblerOptions.back()->setNoMacro();
3431 Parser.Lex(); // Consume the EndOfStatement.
3435 bool MipsAsmParser::parseSetMsaDirective() {
3436 MCAsmParser &Parser = getParser();
3439 // If this is not the end of the statement, report an error.
3440 if (getLexer().isNot(AsmToken::EndOfStatement))
3441 return reportParseError("unexpected token, expected end of statement");
3443 setFeatureBits(Mips::FeatureMSA, "msa");
3444 getTargetStreamer().emitDirectiveSetMsa();
3448 bool MipsAsmParser::parseSetNoMsaDirective() {
3449 MCAsmParser &Parser = getParser();
3452 // If this is not the end of the statement, report an error.
3453 if (getLexer().isNot(AsmToken::EndOfStatement))
3454 return reportParseError("unexpected token, expected end of statement");
3456 clearFeatureBits(Mips::FeatureMSA, "msa");
3457 getTargetStreamer().emitDirectiveSetNoMsa();
3461 bool MipsAsmParser::parseSetNoDspDirective() {
3462 MCAsmParser &Parser = getParser();
3463 Parser.Lex(); // Eat "nodsp".
3465 // If this is not the end of the statement, report an error.
3466 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3467 reportParseError("unexpected token, expected end of statement");
3471 clearFeatureBits(Mips::FeatureDSP, "dsp");
3472 getTargetStreamer().emitDirectiveSetNoDsp();
3476 bool MipsAsmParser::parseSetMips16Directive() {
3477 MCAsmParser &Parser = getParser();
3478 Parser.Lex(); // Eat "mips16".
3480 // If this is not the end of the statement, report an error.
3481 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3482 reportParseError("unexpected token, expected end of statement");
3486 setFeatureBits(Mips::FeatureMips16, "mips16");
3487 getTargetStreamer().emitDirectiveSetMips16();
3488 Parser.Lex(); // Consume the EndOfStatement.
3492 bool MipsAsmParser::parseSetNoMips16Directive() {
3493 MCAsmParser &Parser = getParser();
3494 Parser.Lex(); // Eat "nomips16".
3496 // If this is not the end of the statement, report an error.
3497 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3498 reportParseError("unexpected token, expected end of statement");
3502 clearFeatureBits(Mips::FeatureMips16, "mips16");
3503 getTargetStreamer().emitDirectiveSetNoMips16();
3504 Parser.Lex(); // Consume the EndOfStatement.
3508 bool MipsAsmParser::parseSetFpDirective() {
3509 MCAsmParser &Parser = getParser();
3510 MipsABIFlagsSection::FpABIKind FpAbiVal;
3511 // Line can be: .set fp=32
3514 Parser.Lex(); // Eat fp token
3515 AsmToken Tok = Parser.getTok();
3516 if (Tok.isNot(AsmToken::Equal)) {
3517 reportParseError("unexpected token, expected equals sign '='");
3520 Parser.Lex(); // Eat '=' token.
3521 Tok = Parser.getTok();
3523 if (!parseFpABIValue(FpAbiVal, ".set"))
3526 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3527 reportParseError("unexpected token, expected end of statement");
3530 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3531 Parser.Lex(); // Consume the EndOfStatement.
3535 bool MipsAsmParser::parseSetPopDirective() {
3536 MCAsmParser &Parser = getParser();
3537 SMLoc Loc = getLexer().getLoc();
3540 if (getLexer().isNot(AsmToken::EndOfStatement))
3541 return reportParseError("unexpected token, expected end of statement");
3543 // Always keep an element on the options "stack" to prevent the user
3544 // from changing the initial options. This is how we remember them.
3545 if (AssemblerOptions.size() == 2)
3546 return reportParseError(Loc, ".set pop with no .set push");
3548 AssemblerOptions.pop_back();
3549 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3551 getTargetStreamer().emitDirectiveSetPop();
3555 bool MipsAsmParser::parseSetPushDirective() {
3556 MCAsmParser &Parser = getParser();
3558 if (getLexer().isNot(AsmToken::EndOfStatement))
3559 return reportParseError("unexpected token, expected end of statement");
3561 // Create a copy of the current assembler options environment and push it.
3562 AssemblerOptions.push_back(
3563 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3565 getTargetStreamer().emitDirectiveSetPush();
3569 bool MipsAsmParser::parseSetAssignment() {
3571 const MCExpr *Value;
3572 MCAsmParser &Parser = getParser();
3574 if (Parser.parseIdentifier(Name))
3575 reportParseError("expected identifier after .set");
3577 if (getLexer().isNot(AsmToken::Comma))
3578 return reportParseError("unexpected token, expected comma");
3581 if (Parser.parseExpression(Value))
3582 return reportParseError("expected valid expression after comma");
3584 // Check if the Name already exists as a symbol.
3585 MCSymbol *Sym = getContext().LookupSymbol(Name);
3587 return reportParseError("symbol already defined");
3588 Sym = getContext().GetOrCreateSymbol(Name);
3589 Sym->setVariableValue(Value);
3594 bool MipsAsmParser::parseSetMips0Directive() {
3595 MCAsmParser &Parser = getParser();
3597 if (getLexer().isNot(AsmToken::EndOfStatement))
3598 return reportParseError("unexpected token, expected end of statement");
3600 // Reset assembler options to their initial values.
3601 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3602 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3604 getTargetStreamer().emitDirectiveSetMips0();
3608 bool MipsAsmParser::parseSetArchDirective() {
3609 MCAsmParser &Parser = getParser();
3611 if (getLexer().isNot(AsmToken::Equal))
3612 return reportParseError("unexpected token, expected equals sign");
3616 if (Parser.parseIdentifier(Arch))
3617 return reportParseError("expected arch identifier");
3619 StringRef ArchFeatureName =
3620 StringSwitch<StringRef>(Arch)
3621 .Case("mips1", "mips1")
3622 .Case("mips2", "mips2")
3623 .Case("mips3", "mips3")
3624 .Case("mips4", "mips4")
3625 .Case("mips5", "mips5")
3626 .Case("mips32", "mips32")
3627 .Case("mips32r2", "mips32r2")
3628 .Case("mips32r3", "mips32r3")
3629 .Case("mips32r5", "mips32r5")
3630 .Case("mips32r6", "mips32r6")
3631 .Case("mips64", "mips64")
3632 .Case("mips64r2", "mips64r2")
3633 .Case("mips64r3", "mips64r3")
3634 .Case("mips64r5", "mips64r5")
3635 .Case("mips64r6", "mips64r6")
3636 .Case("cnmips", "cnmips")
3637 .Case("r4000", "mips3") // This is an implementation of Mips3.
3640 if (ArchFeatureName.empty())
3641 return reportParseError("unsupported architecture");
3643 selectArch(ArchFeatureName);
3644 getTargetStreamer().emitDirectiveSetArch(Arch);
3648 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3649 MCAsmParser &Parser = getParser();
3651 if (getLexer().isNot(AsmToken::EndOfStatement))
3652 return reportParseError("unexpected token, expected end of statement");
3656 llvm_unreachable("Unimplemented feature");
3657 case Mips::FeatureDSP:
3658 setFeatureBits(Mips::FeatureDSP, "dsp");
3659 getTargetStreamer().emitDirectiveSetDsp();
3661 case Mips::FeatureMicroMips:
3662 getTargetStreamer().emitDirectiveSetMicroMips();
3664 case Mips::FeatureMips1:
3665 selectArch("mips1");
3666 getTargetStreamer().emitDirectiveSetMips1();
3668 case Mips::FeatureMips2:
3669 selectArch("mips2");
3670 getTargetStreamer().emitDirectiveSetMips2();
3672 case Mips::FeatureMips3:
3673 selectArch("mips3");
3674 getTargetStreamer().emitDirectiveSetMips3();
3676 case Mips::FeatureMips4:
3677 selectArch("mips4");
3678 getTargetStreamer().emitDirectiveSetMips4();
3680 case Mips::FeatureMips5:
3681 selectArch("mips5");
3682 getTargetStreamer().emitDirectiveSetMips5();
3684 case Mips::FeatureMips32:
3685 selectArch("mips32");
3686 getTargetStreamer().emitDirectiveSetMips32();
3688 case Mips::FeatureMips32r2:
3689 selectArch("mips32r2");
3690 getTargetStreamer().emitDirectiveSetMips32R2();
3692 case Mips::FeatureMips32r3:
3693 selectArch("mips32r3");
3694 getTargetStreamer().emitDirectiveSetMips32R3();
3696 case Mips::FeatureMips32r5:
3697 selectArch("mips32r5");
3698 getTargetStreamer().emitDirectiveSetMips32R5();
3700 case Mips::FeatureMips32r6:
3701 selectArch("mips32r6");
3702 getTargetStreamer().emitDirectiveSetMips32R6();
3704 case Mips::FeatureMips64:
3705 selectArch("mips64");
3706 getTargetStreamer().emitDirectiveSetMips64();
3708 case Mips::FeatureMips64r2:
3709 selectArch("mips64r2");
3710 getTargetStreamer().emitDirectiveSetMips64R2();
3712 case Mips::FeatureMips64r3:
3713 selectArch("mips64r3");
3714 getTargetStreamer().emitDirectiveSetMips64R3();
3716 case Mips::FeatureMips64r5:
3717 selectArch("mips64r5");
3718 getTargetStreamer().emitDirectiveSetMips64R5();
3720 case Mips::FeatureMips64r6:
3721 selectArch("mips64r6");
3722 getTargetStreamer().emitDirectiveSetMips64R6();
3728 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3729 MCAsmParser &Parser = getParser();
3730 if (getLexer().isNot(AsmToken::Comma)) {
3731 SMLoc Loc = getLexer().getLoc();
3732 Parser.eatToEndOfStatement();
3733 return Error(Loc, ErrorStr);
3736 Parser.Lex(); // Eat the comma.
3740 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3741 if (AssemblerOptions.back()->isReorder())
3742 Warning(Loc, ".cpload should be inside a noreorder section");
3744 if (inMips16Mode()) {
3745 reportParseError(".cpload is not supported in Mips16 mode");
3749 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3750 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3751 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3752 reportParseError("expected register containing function address");
3756 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3757 if (!RegOpnd.isGPRAsmReg()) {
3758 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3762 // If this is not the end of the statement, report an error.
3763 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3764 reportParseError("unexpected token, expected end of statement");
3768 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3772 bool MipsAsmParser::parseDirectiveCPSetup() {
3773 MCAsmParser &Parser = getParser();
3776 bool SaveIsReg = true;
3778 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3779 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3780 if (ResTy == MatchOperand_NoMatch) {
3781 reportParseError("expected register containing function address");
3782 Parser.eatToEndOfStatement();
3786 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3787 if (!FuncRegOpnd.isGPRAsmReg()) {
3788 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3789 Parser.eatToEndOfStatement();
3793 FuncReg = FuncRegOpnd.getGPR32Reg();
3796 if (!eatComma("unexpected token, expected comma"))
3799 ResTy = parseAnyRegister(TmpReg);
3800 if (ResTy == MatchOperand_NoMatch) {
3801 const AsmToken &Tok = Parser.getTok();
3802 if (Tok.is(AsmToken::Integer)) {
3803 Save = Tok.getIntVal();
3807 reportParseError("expected save register or stack offset");
3808 Parser.eatToEndOfStatement();
3812 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3813 if (!SaveOpnd.isGPRAsmReg()) {
3814 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3815 Parser.eatToEndOfStatement();
3818 Save = SaveOpnd.getGPR32Reg();
3821 if (!eatComma("unexpected token, expected comma"))
3825 if (Parser.parseExpression(Expr)) {
3826 reportParseError("expected expression");
3830 if (Expr->getKind() != MCExpr::SymbolRef) {
3831 reportParseError("expected symbol");
3834 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3836 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3841 bool MipsAsmParser::parseDirectiveNaN() {
3842 MCAsmParser &Parser = getParser();
3843 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3844 const AsmToken &Tok = Parser.getTok();
3846 if (Tok.getString() == "2008") {
3848 getTargetStreamer().emitDirectiveNaN2008();
3850 } else if (Tok.getString() == "legacy") {
3852 getTargetStreamer().emitDirectiveNaNLegacy();
3856 // If we don't recognize the option passed to the .nan
3857 // directive (e.g. no option or unknown option), emit an error.
3858 reportParseError("invalid option in .nan directive");
3862 bool MipsAsmParser::parseDirectiveSet() {
3863 MCAsmParser &Parser = getParser();
3864 // Get the next token.
3865 const AsmToken &Tok = Parser.getTok();
3867 if (Tok.getString() == "noat") {
3868 return parseSetNoAtDirective();
3869 } else if (Tok.getString() == "at") {
3870 return parseSetAtDirective();
3871 } else if (Tok.getString() == "arch") {
3872 return parseSetArchDirective();
3873 } else if (Tok.getString() == "fp") {
3874 return parseSetFpDirective();
3875 } else if (Tok.getString() == "pop") {
3876 return parseSetPopDirective();
3877 } else if (Tok.getString() == "push") {
3878 return parseSetPushDirective();
3879 } else if (Tok.getString() == "reorder") {
3880 return parseSetReorderDirective();
3881 } else if (Tok.getString() == "noreorder") {
3882 return parseSetNoReorderDirective();
3883 } else if (Tok.getString() == "macro") {
3884 return parseSetMacroDirective();
3885 } else if (Tok.getString() == "nomacro") {
3886 return parseSetNoMacroDirective();
3887 } else if (Tok.getString() == "mips16") {
3888 return parseSetMips16Directive();
3889 } else if (Tok.getString() == "nomips16") {
3890 return parseSetNoMips16Directive();
3891 } else if (Tok.getString() == "nomicromips") {
3892 getTargetStreamer().emitDirectiveSetNoMicroMips();
3893 Parser.eatToEndOfStatement();
3895 } else if (Tok.getString() == "micromips") {
3896 return parseSetFeature(Mips::FeatureMicroMips);
3897 } else if (Tok.getString() == "mips0") {
3898 return parseSetMips0Directive();
3899 } else if (Tok.getString() == "mips1") {
3900 return parseSetFeature(Mips::FeatureMips1);
3901 } else if (Tok.getString() == "mips2") {
3902 return parseSetFeature(Mips::FeatureMips2);
3903 } else if (Tok.getString() == "mips3") {
3904 return parseSetFeature(Mips::FeatureMips3);
3905 } else if (Tok.getString() == "mips4") {
3906 return parseSetFeature(Mips::FeatureMips4);
3907 } else if (Tok.getString() == "mips5") {
3908 return parseSetFeature(Mips::FeatureMips5);
3909 } else if (Tok.getString() == "mips32") {
3910 return parseSetFeature(Mips::FeatureMips32);
3911 } else if (Tok.getString() == "mips32r2") {
3912 return parseSetFeature(Mips::FeatureMips32r2);
3913 } else if (Tok.getString() == "mips32r3") {
3914 return parseSetFeature(Mips::FeatureMips32r3);
3915 } else if (Tok.getString() == "mips32r5") {
3916 return parseSetFeature(Mips::FeatureMips32r5);
3917 } else if (Tok.getString() == "mips32r6") {
3918 return parseSetFeature(Mips::FeatureMips32r6);
3919 } else if (Tok.getString() == "mips64") {
3920 return parseSetFeature(Mips::FeatureMips64);
3921 } else if (Tok.getString() == "mips64r2") {
3922 return parseSetFeature(Mips::FeatureMips64r2);
3923 } else if (Tok.getString() == "mips64r3") {
3924 return parseSetFeature(Mips::FeatureMips64r3);
3925 } else if (Tok.getString() == "mips64r5") {
3926 return parseSetFeature(Mips::FeatureMips64r5);
3927 } else if (Tok.getString() == "mips64r6") {
3928 return parseSetFeature(Mips::FeatureMips64r6);
3929 } else if (Tok.getString() == "dsp") {
3930 return parseSetFeature(Mips::FeatureDSP);
3931 } else if (Tok.getString() == "nodsp") {
3932 return parseSetNoDspDirective();
3933 } else if (Tok.getString() == "msa") {
3934 return parseSetMsaDirective();
3935 } else if (Tok.getString() == "nomsa") {
3936 return parseSetNoMsaDirective();
3938 // It is just an identifier, look for an assignment.
3939 parseSetAssignment();
3946 /// parseDataDirective
3947 /// ::= .word [ expression (, expression)* ]
3948 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3949 MCAsmParser &Parser = getParser();
3950 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3952 const MCExpr *Value;
3953 if (getParser().parseExpression(Value))
3956 getParser().getStreamer().EmitValue(Value, Size);
3958 if (getLexer().is(AsmToken::EndOfStatement))
3961 if (getLexer().isNot(AsmToken::Comma))
3962 return Error(L, "unexpected token, expected comma");
3971 /// parseDirectiveGpWord
3972 /// ::= .gpword local_sym
3973 bool MipsAsmParser::parseDirectiveGpWord() {
3974 MCAsmParser &Parser = getParser();
3975 const MCExpr *Value;
3976 // EmitGPRel32Value requires an expression, so we are using base class
3977 // method to evaluate the expression.
3978 if (getParser().parseExpression(Value))
3980 getParser().getStreamer().EmitGPRel32Value(Value);
3982 if (getLexer().isNot(AsmToken::EndOfStatement))
3983 return Error(getLexer().getLoc(),
3984 "unexpected token, expected end of statement");
3985 Parser.Lex(); // Eat EndOfStatement token.
3989 /// parseDirectiveGpDWord
3990 /// ::= .gpdword local_sym
3991 bool MipsAsmParser::parseDirectiveGpDWord() {
3992 MCAsmParser &Parser = getParser();
3993 const MCExpr *Value;
3994 // EmitGPRel64Value requires an expression, so we are using base class
3995 // method to evaluate the expression.
3996 if (getParser().parseExpression(Value))
3998 getParser().getStreamer().EmitGPRel64Value(Value);
4000 if (getLexer().isNot(AsmToken::EndOfStatement))
4001 return Error(getLexer().getLoc(),
4002 "unexpected token, expected end of statement");
4003 Parser.Lex(); // Eat EndOfStatement token.
4007 bool MipsAsmParser::parseDirectiveOption() {
4008 MCAsmParser &Parser = getParser();
4009 // Get the option token.
4010 AsmToken Tok = Parser.getTok();
4011 // At the moment only identifiers are supported.
4012 if (Tok.isNot(AsmToken::Identifier)) {
4013 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4014 Parser.eatToEndOfStatement();
4018 StringRef Option = Tok.getIdentifier();
4020 if (Option == "pic0") {
4021 getTargetStreamer().emitDirectiveOptionPic0();
4023 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4024 Error(Parser.getTok().getLoc(),
4025 "unexpected token, expected end of statement");
4026 Parser.eatToEndOfStatement();
4031 if (Option == "pic2") {
4032 getTargetStreamer().emitDirectiveOptionPic2();
4034 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4035 Error(Parser.getTok().getLoc(),
4036 "unexpected token, expected end of statement");
4037 Parser.eatToEndOfStatement();
4043 Warning(Parser.getTok().getLoc(),
4044 "unknown option, expected 'pic0' or 'pic2'");
4045 Parser.eatToEndOfStatement();
4049 /// parseDirectiveModule
4050 /// ::= .module oddspreg
4051 /// ::= .module nooddspreg
4052 /// ::= .module fp=value
4053 bool MipsAsmParser::parseDirectiveModule() {
4054 MCAsmParser &Parser = getParser();
4055 MCAsmLexer &Lexer = getLexer();
4056 SMLoc L = Lexer.getLoc();
4058 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4059 // TODO : get a better message.
4060 reportParseError(".module directive must appear before any code");
4065 if (Parser.parseIdentifier(Option)) {
4066 reportParseError("expected .module option identifier");
4070 if (Option == "oddspreg") {
4071 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4072 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4074 // If this is not the end of the statement, report an error.
4075 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4076 reportParseError("unexpected token, expected end of statement");
4080 return false; // parseDirectiveModule has finished successfully.
4081 } else if (Option == "nooddspreg") {
4083 Error(L, "'.module nooddspreg' requires the O32 ABI");
4087 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4088 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4090 // If this is not the end of the statement, report an error.
4091 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4092 reportParseError("unexpected token, expected end of statement");
4096 return false; // parseDirectiveModule has finished successfully.
4097 } else if (Option == "fp") {
4098 return parseDirectiveModuleFP();
4100 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4104 /// parseDirectiveModuleFP
4108 bool MipsAsmParser::parseDirectiveModuleFP() {
4109 MCAsmParser &Parser = getParser();
4110 MCAsmLexer &Lexer = getLexer();
4112 if (Lexer.isNot(AsmToken::Equal)) {
4113 reportParseError("unexpected token, expected equals sign '='");
4116 Parser.Lex(); // Eat '=' token.
4118 MipsABIFlagsSection::FpABIKind FpABI;
4119 if (!parseFpABIValue(FpABI, ".module"))
4122 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4123 reportParseError("unexpected token, expected end of statement");
4127 // Emit appropriate flags.
4128 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4129 Parser.Lex(); // Consume the EndOfStatement.
4133 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4134 StringRef Directive) {
4135 MCAsmParser &Parser = getParser();
4136 MCAsmLexer &Lexer = getLexer();
4138 if (Lexer.is(AsmToken::Identifier)) {
4139 StringRef Value = Parser.getTok().getString();
4142 if (Value != "xx") {
4143 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4148 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4152 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4156 if (Lexer.is(AsmToken::Integer)) {
4157 unsigned Value = Parser.getTok().getIntVal();
4160 if (Value != 32 && Value != 64) {
4161 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4167 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4171 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4173 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4181 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4182 MCAsmParser &Parser = getParser();
4183 StringRef IDVal = DirectiveID.getString();
4185 if (IDVal == ".cpload")
4186 return parseDirectiveCpLoad(DirectiveID.getLoc());
4187 if (IDVal == ".dword") {
4188 parseDataDirective(8, DirectiveID.getLoc());
4191 if (IDVal == ".ent") {
4192 StringRef SymbolName;
4194 if (Parser.parseIdentifier(SymbolName)) {
4195 reportParseError("expected identifier after .ent");
4199 // There's an undocumented extension that allows an integer to
4200 // follow the name of the procedure which AFAICS is ignored by GAS.
4201 // Example: .ent foo,2
4202 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4203 if (getLexer().isNot(AsmToken::Comma)) {
4204 // Even though we accept this undocumented extension for compatibility
4205 // reasons, the additional integer argument does not actually change
4206 // the behaviour of the '.ent' directive, so we would like to discourage
4207 // its use. We do this by not referring to the extended version in
4208 // error messages which are not directly related to its use.
4209 reportParseError("unexpected token, expected end of statement");
4212 Parser.Lex(); // Eat the comma.
4213 const MCExpr *DummyNumber;
4214 int64_t DummyNumberVal;
4215 // If the user was explicitly trying to use the extended version,
4216 // we still give helpful extension-related error messages.
4217 if (Parser.parseExpression(DummyNumber)) {
4218 reportParseError("expected number after comma");
4221 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4222 reportParseError("expected an absolute expression after comma");
4227 // If this is not the end of the statement, report an error.
4228 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4229 reportParseError("unexpected token, expected end of statement");
4233 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4235 getTargetStreamer().emitDirectiveEnt(*Sym);
4240 if (IDVal == ".end") {
4241 StringRef SymbolName;
4243 if (Parser.parseIdentifier(SymbolName)) {
4244 reportParseError("expected identifier after .end");
4248 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4249 reportParseError("unexpected token, expected end of statement");
4253 if (CurrentFn == nullptr) {
4254 reportParseError(".end used without .ent");
4258 if ((SymbolName != CurrentFn->getName())) {
4259 reportParseError(".end symbol does not match .ent symbol");
4263 getTargetStreamer().emitDirectiveEnd(SymbolName);
4264 CurrentFn = nullptr;
4268 if (IDVal == ".frame") {
4269 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4270 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4271 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4272 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4273 reportParseError("expected stack register");
4277 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4278 if (!StackRegOpnd.isGPRAsmReg()) {
4279 reportParseError(StackRegOpnd.getStartLoc(),
4280 "expected general purpose register");
4283 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4285 if (Parser.getTok().is(AsmToken::Comma))
4288 reportParseError("unexpected token, expected comma");
4292 // Parse the frame size.
4293 const MCExpr *FrameSize;
4294 int64_t FrameSizeVal;
4296 if (Parser.parseExpression(FrameSize)) {
4297 reportParseError("expected frame size value");
4301 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4302 reportParseError("frame size not an absolute expression");
4306 if (Parser.getTok().is(AsmToken::Comma))
4309 reportParseError("unexpected token, expected comma");
4313 // Parse the return register.
4315 ResTy = parseAnyRegister(TmpReg);
4316 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4317 reportParseError("expected return register");
4321 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4322 if (!ReturnRegOpnd.isGPRAsmReg()) {
4323 reportParseError(ReturnRegOpnd.getStartLoc(),
4324 "expected general purpose register");
4328 // If this is not the end of the statement, report an error.
4329 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4330 reportParseError("unexpected token, expected end of statement");
4334 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4335 ReturnRegOpnd.getGPR32Reg());
4339 if (IDVal == ".set") {
4340 return parseDirectiveSet();
4343 if (IDVal == ".mask" || IDVal == ".fmask") {
4344 // .mask bitmask, frame_offset
4345 // bitmask: One bit for each register used.
4346 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4347 // first register is expected to be saved.
4349 // .mask 0x80000000, -4
4350 // .fmask 0x80000000, -4
4353 // Parse the bitmask
4354 const MCExpr *BitMask;
4357 if (Parser.parseExpression(BitMask)) {
4358 reportParseError("expected bitmask value");
4362 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4363 reportParseError("bitmask not an absolute expression");
4367 if (Parser.getTok().is(AsmToken::Comma))
4370 reportParseError("unexpected token, expected comma");
4374 // Parse the frame_offset
4375 const MCExpr *FrameOffset;
4376 int64_t FrameOffsetVal;
4378 if (Parser.parseExpression(FrameOffset)) {
4379 reportParseError("expected frame offset value");
4383 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4384 reportParseError("frame offset not an absolute expression");
4388 // If this is not the end of the statement, report an error.
4389 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4390 reportParseError("unexpected token, expected end of statement");
4394 if (IDVal == ".mask")
4395 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4397 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4401 if (IDVal == ".nan")
4402 return parseDirectiveNaN();
4404 if (IDVal == ".gpword") {
4405 parseDirectiveGpWord();
4409 if (IDVal == ".gpdword") {
4410 parseDirectiveGpDWord();
4414 if (IDVal == ".word") {
4415 parseDataDirective(4, DirectiveID.getLoc());
4419 if (IDVal == ".option")
4420 return parseDirectiveOption();
4422 if (IDVal == ".abicalls") {
4423 getTargetStreamer().emitDirectiveAbiCalls();
4424 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4425 Error(Parser.getTok().getLoc(),
4426 "unexpected token, expected end of statement");
4428 Parser.eatToEndOfStatement();
4433 if (IDVal == ".cpsetup")
4434 return parseDirectiveCPSetup();
4436 if (IDVal == ".module")
4437 return parseDirectiveModule();
4439 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4440 return parseInternalDirectiveReallowModule();
4445 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4446 // If this is not the end of the statement, report an error.
4447 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4448 reportParseError("unexpected token, expected end of statement");
4452 getTargetStreamer().reallowModuleDirective();
4454 getParser().Lex(); // Eat EndOfStatement token.
4458 extern "C" void LLVMInitializeMipsAsmParser() {
4459 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4460 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4461 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4462 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4465 #define GET_REGISTER_MATCHER
4466 #define GET_MATCHER_IMPLEMENTATION
4467 #include "MipsGenAsmMatcher.inc"