1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(uint64_t Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegIndex();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegIndex() const { return ATReg; }
57 bool setATRegIndex(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 uint64_t getFeatures() const { return Features; }
74 void setFeatures(uint64_t Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const uint64_t AllArchRelatedMask =
82 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
83 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
84 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
85 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
86 Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
87 Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
88 Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
89 Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
100 class MipsAsmParser : public MCTargetAsmParser {
101 MipsTargetStreamer &getTargetStreamer() {
102 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
103 return static_cast<MipsTargetStreamer &>(TS);
106 MCSubtargetInfo &STI;
108 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
109 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
110 // nullptr, which indicates that no function is currently
111 // selected. This usually happens after an '.end func'
114 // Print a warning along with its fix-it message at the given range.
115 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
116 SMRange Range, bool ShowColors = true);
118 #define GET_ASSEMBLER_HEADER
119 #include "MipsGenAsmMatcher.inc"
121 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
123 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
124 OperandVector &Operands, MCStreamer &Out,
126 bool MatchingInlineAsm) override;
128 /// Parse a register as used in CFI directives
129 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
131 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
133 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
135 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
136 SMLoc NameLoc, OperandVector &Operands) override;
138 bool ParseDirective(AsmToken DirectiveID) override;
140 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
142 MipsAsmParser::OperandMatchResultTy
143 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
144 StringRef Identifier, SMLoc S);
146 MipsAsmParser::OperandMatchResultTy
147 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
151 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
153 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy
160 parseRegisterPair (OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseMovePRegPair(OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseRegisterList (OperandVector &Operands);
168 bool searchSymbolAlias(OperandVector &Operands);
170 bool parseOperand(OperandVector &, StringRef Mnemonic);
172 bool needsExpansion(MCInst &Inst);
174 // Expands assembly pseudo instructions.
175 // Returns false on success, true otherwise.
176 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
190 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
200 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
203 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 bool reportParseError(Twine ErrorMsg);
207 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
209 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
210 bool parseRelocOperand(const MCExpr *&Res);
212 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
214 bool isEvaluated(const MCExpr *Expr);
215 bool parseSetMips0Directive();
216 bool parseSetArchDirective();
217 bool parseSetFeature(uint64_t Feature);
218 bool parseDirectiveCpLoad(SMLoc Loc);
219 bool parseDirectiveCPSetup();
220 bool parseDirectiveNaN();
221 bool parseDirectiveSet();
222 bool parseDirectiveOption();
223 bool parseInsnDirective();
225 bool parseSetAtDirective();
226 bool parseSetNoAtDirective();
227 bool parseSetMacroDirective();
228 bool parseSetNoMacroDirective();
229 bool parseSetMsaDirective();
230 bool parseSetNoMsaDirective();
231 bool parseSetNoDspDirective();
232 bool parseSetReorderDirective();
233 bool parseSetNoReorderDirective();
234 bool parseSetMips16Directive();
235 bool parseSetNoMips16Directive();
236 bool parseSetFpDirective();
237 bool parseSetPopDirective();
238 bool parseSetPushDirective();
240 bool parseSetAssignment();
242 bool parseDataDirective(unsigned Size, SMLoc L);
243 bool parseDirectiveGpWord();
244 bool parseDirectiveGpDWord();
245 bool parseDirectiveModule();
246 bool parseDirectiveModuleFP();
247 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
248 StringRef Directive);
250 bool parseInternalDirectiveReallowModule();
252 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
254 bool eatComma(StringRef ErrorStr);
256 int matchCPURegisterName(StringRef Symbol);
258 int matchHWRegsRegisterName(StringRef Symbol);
260 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
262 int matchFPURegisterName(StringRef Name);
264 int matchFCCRegisterName(StringRef Name);
266 int matchACRegisterName(StringRef Name);
268 int matchMSA128RegisterName(StringRef Name);
270 int matchMSA128CtrlRegisterName(StringRef Name);
272 unsigned getReg(int RC, int RegNo);
274 unsigned getGPR(int RegNo);
276 /// Returns the internal register number for the current AT. Also checks if
277 /// the current AT is unavailable (set to $0) and gives an error if it is.
278 /// This should be used in pseudo-instruction expansions which need AT.
279 unsigned getATReg(SMLoc Loc);
281 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
282 SmallVectorImpl<MCInst> &Instructions);
284 // Helper function that checks if the value of a vector index is within the
285 // boundaries of accepted values for each RegisterKind
286 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
287 bool validateMSAIndex(int Val, int RegKind);
289 // Selects a new architecture by updating the FeatureBits with the necessary
290 // info including implied dependencies.
291 // Internally, it clears all the feature bits related to *any* architecture
292 // and selects the new one using the ToggleFeature functionality of the
293 // MCSubtargetInfo object that handles implied dependencies. The reason we
294 // clear all the arch related bits manually is because ToggleFeature only
295 // clears the features that imply the feature being cleared and not the
296 // features implied by the feature being cleared. This is easier to see
298 // --------------------------------------------------
299 // | Feature | Implies |
300 // | -------------------------------------------------|
301 // | FeatureMips1 | None |
302 // | FeatureMips2 | FeatureMips1 |
303 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
304 // | FeatureMips4 | FeatureMips3 |
306 // --------------------------------------------------
308 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
309 // FeatureMipsGP64 | FeatureMips1)
310 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
311 void selectArch(StringRef ArchFeature) {
312 uint64_t FeatureBits = STI.getFeatureBits();
313 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
314 STI.setFeatureBits(FeatureBits);
315 setAvailableFeatures(
316 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
317 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
320 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
321 if (!(STI.getFeatureBits() & Feature)) {
322 setAvailableFeatures(
323 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
325 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
328 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
329 if (STI.getFeatureBits() & Feature) {
330 setAvailableFeatures(
331 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
333 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
337 enum MipsMatchResultTy {
338 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
339 #define GET_OPERAND_DIAGNOSTIC_TYPES
340 #include "MipsGenAsmMatcher.inc"
341 #undef GET_OPERAND_DIAGNOSTIC_TYPES
345 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
346 const MCInstrInfo &MII, const MCTargetOptions &Options)
347 : MCTargetAsmParser(), STI(sti),
348 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
349 sti.getCPU(), Options)) {
350 MCAsmParserExtension::Initialize(parser);
352 parser.addAliasForDirective(".asciiz", ".asciz");
354 // Initialize the set of available features.
355 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
357 // Remember the initial assembler options. The user can not modify these.
358 AssemblerOptions.push_back(
359 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
361 // Create an assembler options environment for the user to modify.
362 AssemblerOptions.push_back(
363 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
365 getTargetStreamer().updateABIInfo(*this);
367 if (!isABI_O32() && !useOddSPReg() != 0)
368 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
373 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
374 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
376 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
377 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
378 const MipsABIInfo &getABI() const { return ABI; }
379 bool isABI_N32() const { return ABI.IsN32(); }
380 bool isABI_N64() const { return ABI.IsN64(); }
381 bool isABI_O32() const { return ABI.IsO32(); }
382 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
384 bool useOddSPReg() const {
385 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
388 bool inMicroMipsMode() const {
389 return STI.getFeatureBits() & Mips::FeatureMicroMips;
391 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
392 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
393 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
394 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
395 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
396 bool hasMips32() const {
397 return (STI.getFeatureBits() & Mips::FeatureMips32);
399 bool hasMips64() const {
400 return (STI.getFeatureBits() & Mips::FeatureMips64);
402 bool hasMips32r2() const {
403 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
405 bool hasMips64r2() const {
406 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
408 bool hasMips32r3() const {
409 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
411 bool hasMips64r3() const {
412 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
414 bool hasMips32r5() const {
415 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
417 bool hasMips64r5() const {
418 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
420 bool hasMips32r6() const {
421 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
423 bool hasMips64r6() const {
424 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
426 bool hasCnMips() const {
427 return (STI.getFeatureBits() & Mips::FeatureCnMips);
429 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
430 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
431 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
433 bool inMips16Mode() const {
434 return STI.getFeatureBits() & Mips::FeatureMips16;
437 bool useSoftFloat() const {
438 return (STI.getFeatureBits() & Mips::FeatureSoftFloat);
441 /// Warn if RegIndex is the same as the current AT.
442 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
448 /// MipsOperand - Instances of this class represent a parsed Mips machine
450 class MipsOperand : public MCParsedAsmOperand {
452 /// Broad categories of register classes
453 /// The exact class is finalized by the render method.
455 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
456 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
458 RegKind_FCC = 4, /// FCC
459 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
460 RegKind_MSACtrl = 16, /// MSA control registers
461 RegKind_COP2 = 32, /// COP2
462 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
464 RegKind_CCR = 128, /// CCR
465 RegKind_HWRegs = 256, /// HWRegs
466 RegKind_COP3 = 512, /// COP3
468 /// Potentially any (e.g. $1)
469 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
470 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
471 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
476 k_Immediate, /// An immediate (possibly involving symbol references)
477 k_Memory, /// Base + Offset Memory Address
478 k_PhysRegister, /// A physical register from the Mips namespace
479 k_RegisterIndex, /// A register index in one or more RegKind.
480 k_Token, /// A simple token
481 k_RegList, /// A physical register list
482 k_RegPair /// A pair of physical register
486 MipsOperand(KindTy K, MipsAsmParser &Parser)
487 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
490 /// For diagnostics, and checking the assembler temporary
491 MipsAsmParser &AsmParser;
499 unsigned Num; /// Register Number
503 unsigned Index; /// Index into the register class
504 RegKind Kind; /// Bitfield of the kinds it could possibly be
505 const MCRegisterInfo *RegInfo;
518 SmallVector<unsigned, 10> *List;
523 struct PhysRegOp PhysReg;
524 struct RegIdxOp RegIdx;
527 struct RegListOp RegList;
530 SMLoc StartLoc, EndLoc;
532 /// Internal constructor for register kinds
533 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
534 const MCRegisterInfo *RegInfo,
536 MipsAsmParser &Parser) {
537 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
538 Op->RegIdx.Index = Index;
539 Op->RegIdx.RegInfo = RegInfo;
540 Op->RegIdx.Kind = RegKind;
547 /// Coerce the register to GPR32 and return the real register for the current
549 unsigned getGPR32Reg() const {
550 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
551 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
552 unsigned ClassID = Mips::GPR32RegClassID;
553 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
556 /// Coerce the register to GPR32 and return the real register for the current
558 unsigned getGPRMM16Reg() const {
559 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
560 unsigned ClassID = Mips::GPR32RegClassID;
561 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
564 /// Coerce the register to GPR64 and return the real register for the current
566 unsigned getGPR64Reg() const {
567 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
568 unsigned ClassID = Mips::GPR64RegClassID;
569 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
573 /// Coerce the register to AFGR64 and return the real register for the current
575 unsigned getAFGR64Reg() const {
576 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
577 if (RegIdx.Index % 2 != 0)
578 AsmParser.Warning(StartLoc, "Float register should be even.");
579 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
580 .getRegister(RegIdx.Index / 2);
583 /// Coerce the register to FGR64 and return the real register for the current
585 unsigned getFGR64Reg() const {
586 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
587 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
588 .getRegister(RegIdx.Index);
591 /// Coerce the register to FGR32 and return the real register for the current
593 unsigned getFGR32Reg() const {
594 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
595 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
596 .getRegister(RegIdx.Index);
599 /// Coerce the register to FGRH32 and return the real register for the current
601 unsigned getFGRH32Reg() const {
602 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
603 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
604 .getRegister(RegIdx.Index);
607 /// Coerce the register to FCC and return the real register for the current
609 unsigned getFCCReg() const {
610 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
611 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
612 .getRegister(RegIdx.Index);
615 /// Coerce the register to MSA128 and return the real register for the current
617 unsigned getMSA128Reg() const {
618 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
619 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
621 unsigned ClassID = Mips::MSA128BRegClassID;
622 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
625 /// Coerce the register to MSACtrl and return the real register for the
627 unsigned getMSACtrlReg() const {
628 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
629 unsigned ClassID = Mips::MSACtrlRegClassID;
630 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
633 /// Coerce the register to COP2 and return the real register for the
635 unsigned getCOP2Reg() const {
636 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
637 unsigned ClassID = Mips::COP2RegClassID;
638 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
641 /// Coerce the register to COP3 and return the real register for the
643 unsigned getCOP3Reg() const {
644 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
645 unsigned ClassID = Mips::COP3RegClassID;
646 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
649 /// Coerce the register to ACC64DSP and return the real register for the
651 unsigned getACC64DSPReg() const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
653 unsigned ClassID = Mips::ACC64DSPRegClassID;
654 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
657 /// Coerce the register to HI32DSP and return the real register for the
659 unsigned getHI32DSPReg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
661 unsigned ClassID = Mips::HI32DSPRegClassID;
662 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
665 /// Coerce the register to LO32DSP and return the real register for the
667 unsigned getLO32DSPReg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
669 unsigned ClassID = Mips::LO32DSPRegClassID;
670 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
673 /// Coerce the register to CCR and return the real register for the
675 unsigned getCCRReg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
677 unsigned ClassID = Mips::CCRRegClassID;
678 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
681 /// Coerce the register to HWRegs and return the real register for the
683 unsigned getHWRegsReg() const {
684 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
685 unsigned ClassID = Mips::HWRegsRegClassID;
686 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
690 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
691 // Add as immediate when possible. Null MCExpr = 0.
693 Inst.addOperand(MCOperand::CreateImm(0));
694 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
695 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
697 Inst.addOperand(MCOperand::CreateExpr(Expr));
700 void addRegOperands(MCInst &Inst, unsigned N) const {
701 llvm_unreachable("Use a custom parser instead");
704 /// Render the operand to an MCInst as a GPR32
705 /// Asserts if the wrong number of operands are requested, or the operand
706 /// is not a k_RegisterIndex compatible with RegKind_GPR
707 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
708 assert(N == 1 && "Invalid number of operands!");
709 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
712 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
713 assert(N == 1 && "Invalid number of operands!");
714 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
717 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
718 assert(N == 1 && "Invalid number of operands!");
719 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
722 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
723 assert(N == 1 && "Invalid number of operands!");
724 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
727 /// Render the operand to an MCInst as a GPR64
728 /// Asserts if the wrong number of operands are requested, or the operand
729 /// is not a k_RegisterIndex compatible with RegKind_GPR
730 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
731 assert(N == 1 && "Invalid number of operands!");
732 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
735 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
736 assert(N == 1 && "Invalid number of operands!");
737 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
740 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
741 assert(N == 1 && "Invalid number of operands!");
742 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
745 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
746 assert(N == 1 && "Invalid number of operands!");
747 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
748 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
749 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
750 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
754 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
759 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
764 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
765 assert(N == 1 && "Invalid number of operands!");
766 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
769 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
770 assert(N == 1 && "Invalid number of operands!");
771 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
774 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
775 assert(N == 1 && "Invalid number of operands!");
776 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
779 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
780 assert(N == 1 && "Invalid number of operands!");
781 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
784 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
785 assert(N == 1 && "Invalid number of operands!");
786 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
789 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
790 assert(N == 1 && "Invalid number of operands!");
791 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
794 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
795 assert(N == 1 && "Invalid number of operands!");
796 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
799 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
800 assert(N == 1 && "Invalid number of operands!");
801 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
804 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
805 assert(N == 1 && "Invalid number of operands!");
806 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
809 void addImmOperands(MCInst &Inst, unsigned N) const {
810 assert(N == 1 && "Invalid number of operands!");
811 const MCExpr *Expr = getImm();
815 void addMemOperands(MCInst &Inst, unsigned N) const {
816 assert(N == 2 && "Invalid number of operands!");
818 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
820 const MCExpr *Expr = getMemOff();
824 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
825 assert(N == 2 && "Invalid number of operands!");
827 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
829 const MCExpr *Expr = getMemOff();
833 void addRegListOperands(MCInst &Inst, unsigned N) const {
834 assert(N == 1 && "Invalid number of operands!");
836 for (auto RegNo : getRegList())
837 Inst.addOperand(MCOperand::CreateReg(RegNo));
840 void addRegPairOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 2 && "Invalid number of operands!");
842 unsigned RegNo = getRegPair();
843 Inst.addOperand(MCOperand::CreateReg(RegNo++));
844 Inst.addOperand(MCOperand::CreateReg(RegNo));
847 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 2 && "Invalid number of operands!");
849 for (auto RegNo : getRegList())
850 Inst.addOperand(MCOperand::CreateReg(RegNo));
853 bool isReg() const override {
854 // As a special case until we sort out the definition of div/divu, pretend
855 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
856 if (isGPRAsmReg() && RegIdx.Index == 0)
859 return Kind == k_PhysRegister;
861 bool isRegIdx() const { return Kind == k_RegisterIndex; }
862 bool isImm() const override { return Kind == k_Immediate; }
863 bool isConstantImm() const {
864 return isImm() && dyn_cast<MCConstantExpr>(getImm());
866 bool isToken() const override {
867 // Note: It's not possible to pretend that other operand kinds are tokens.
868 // The matcher emitter checks tokens first.
869 return Kind == k_Token;
871 bool isMem() const override { return Kind == k_Memory; }
872 bool isConstantMemOff() const {
873 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
875 template <unsigned Bits> bool isMemWithSimmOffset() const {
876 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
878 bool isMemWithGRPMM16Base() const {
879 return isMem() && getMemBase()->isMM16AsmReg();
881 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
882 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
883 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
885 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
886 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
887 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
888 && (getMemBase()->getGPR32Reg() == Mips::SP);
890 bool isRegList16() const {
894 int Size = RegList.List->size();
895 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
896 RegList.List->back() != Mips::RA)
899 int PrevReg = *RegList.List->begin();
900 for (int i = 1; i < Size - 1; i++) {
901 int Reg = (*(RegList.List))[i];
902 if ( Reg != PrevReg + 1)
909 bool isInvNum() const { return Kind == k_Immediate; }
910 bool isLSAImm() const {
911 if (!isConstantImm())
913 int64_t Val = getConstantImm();
914 return 1 <= Val && Val <= 4;
916 bool isRegList() const { return Kind == k_RegList; }
917 bool isMovePRegPair() const {
918 if (Kind != k_RegList || RegList.List->size() != 2)
921 unsigned R0 = RegList.List->front();
922 unsigned R1 = RegList.List->back();
924 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
925 (R0 == Mips::A1 && R1 == Mips::A3) ||
926 (R0 == Mips::A2 && R1 == Mips::A3) ||
927 (R0 == Mips::A0 && R1 == Mips::S5) ||
928 (R0 == Mips::A0 && R1 == Mips::S6) ||
929 (R0 == Mips::A0 && R1 == Mips::A1) ||
930 (R0 == Mips::A0 && R1 == Mips::A2) ||
931 (R0 == Mips::A0 && R1 == Mips::A3))
937 StringRef getToken() const {
938 assert(Kind == k_Token && "Invalid access!");
939 return StringRef(Tok.Data, Tok.Length);
941 bool isRegPair() const { return Kind == k_RegPair; }
943 unsigned getReg() const override {
944 // As a special case until we sort out the definition of div/divu, pretend
945 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
946 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
947 RegIdx.Kind & RegKind_GPR)
948 return getGPR32Reg(); // FIXME: GPR64 too
950 assert(Kind == k_PhysRegister && "Invalid access!");
954 const MCExpr *getImm() const {
955 assert((Kind == k_Immediate) && "Invalid access!");
959 int64_t getConstantImm() const {
960 const MCExpr *Val = getImm();
961 return static_cast<const MCConstantExpr *>(Val)->getValue();
964 MipsOperand *getMemBase() const {
965 assert((Kind == k_Memory) && "Invalid access!");
969 const MCExpr *getMemOff() const {
970 assert((Kind == k_Memory) && "Invalid access!");
974 int64_t getConstantMemOff() const {
975 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
978 const SmallVectorImpl<unsigned> &getRegList() const {
979 assert((Kind == k_RegList) && "Invalid access!");
980 return *(RegList.List);
983 unsigned getRegPair() const {
984 assert((Kind == k_RegPair) && "Invalid access!");
988 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
989 MipsAsmParser &Parser) {
990 auto Op = make_unique<MipsOperand>(k_Token, Parser);
991 Op->Tok.Data = Str.data();
992 Op->Tok.Length = Str.size();
998 /// Create a numeric register (e.g. $1). The exact register remains
999 /// unresolved until an instruction successfully matches
1000 static std::unique_ptr<MipsOperand>
1001 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1002 SMLoc E, MipsAsmParser &Parser) {
1003 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1004 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1007 /// Create a register that is definitely a GPR.
1008 /// This is typically only used for named registers such as $gp.
1009 static std::unique_ptr<MipsOperand>
1010 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1011 MipsAsmParser &Parser) {
1012 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1015 /// Create a register that is definitely a FGR.
1016 /// This is typically only used for named registers such as $f0.
1017 static std::unique_ptr<MipsOperand>
1018 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1019 MipsAsmParser &Parser) {
1020 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1023 /// Create a register that is definitely a HWReg.
1024 /// This is typically only used for named registers such as $hwr_cpunum.
1025 static std::unique_ptr<MipsOperand>
1026 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1027 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1028 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1031 /// Create a register that is definitely an FCC.
1032 /// This is typically only used for named registers such as $fcc0.
1033 static std::unique_ptr<MipsOperand>
1034 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1035 MipsAsmParser &Parser) {
1036 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1039 /// Create a register that is definitely an ACC.
1040 /// This is typically only used for named registers such as $ac0.
1041 static std::unique_ptr<MipsOperand>
1042 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1043 MipsAsmParser &Parser) {
1044 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1047 /// Create a register that is definitely an MSA128.
1048 /// This is typically only used for named registers such as $w0.
1049 static std::unique_ptr<MipsOperand>
1050 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1051 SMLoc E, MipsAsmParser &Parser) {
1052 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1055 /// Create a register that is definitely an MSACtrl.
1056 /// This is typically only used for named registers such as $msaaccess.
1057 static std::unique_ptr<MipsOperand>
1058 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1059 SMLoc E, MipsAsmParser &Parser) {
1060 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1063 static std::unique_ptr<MipsOperand>
1064 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1065 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1072 static std::unique_ptr<MipsOperand>
1073 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1074 SMLoc E, MipsAsmParser &Parser) {
1075 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1076 Op->Mem.Base = Base.release();
1083 static std::unique_ptr<MipsOperand>
1084 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1085 MipsAsmParser &Parser) {
1086 assert (Regs.size() > 0 && "Empty list not allowed");
1088 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1089 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1090 Op->StartLoc = StartLoc;
1091 Op->EndLoc = EndLoc;
1095 static std::unique_ptr<MipsOperand>
1096 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1097 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1098 Op->RegIdx.Index = RegNo;
1104 bool isGPRAsmReg() const {
1105 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1107 bool isMM16AsmReg() const {
1108 if (!(isRegIdx() && RegIdx.Kind))
1110 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1111 || RegIdx.Index == 16 || RegIdx.Index == 17);
1113 bool isMM16AsmRegZero() const {
1114 if (!(isRegIdx() && RegIdx.Kind))
1116 return (RegIdx.Index == 0 ||
1117 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1118 RegIdx.Index == 17);
1120 bool isMM16AsmRegMoveP() const {
1121 if (!(isRegIdx() && RegIdx.Kind))
1123 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1124 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1126 bool isFGRAsmReg() const {
1127 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1128 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1130 bool isHWRegsAsmReg() const {
1131 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1133 bool isCCRAsmReg() const {
1134 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1136 bool isFCCAsmReg() const {
1137 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1139 if (!AsmParser.hasEightFccRegisters())
1140 return RegIdx.Index == 0;
1141 return RegIdx.Index <= 7;
1143 bool isACCAsmReg() const {
1144 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1146 bool isCOP2AsmReg() const {
1147 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1149 bool isCOP3AsmReg() const {
1150 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1152 bool isMSA128AsmReg() const {
1153 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1155 bool isMSACtrlAsmReg() const {
1156 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1159 /// getStartLoc - Get the location of the first token of this operand.
1160 SMLoc getStartLoc() const override { return StartLoc; }
1161 /// getEndLoc - Get the location of the last token of this operand.
1162 SMLoc getEndLoc() const override { return EndLoc; }
1164 virtual ~MipsOperand() {
1172 delete RegList.List;
1173 case k_PhysRegister:
1174 case k_RegisterIndex:
1181 void print(raw_ostream &OS) const override {
1190 Mem.Base->print(OS);
1195 case k_PhysRegister:
1196 OS << "PhysReg<" << PhysReg.Num << ">";
1198 case k_RegisterIndex:
1199 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1206 for (auto Reg : (*RegList.List))
1211 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1215 }; // class MipsOperand
1219 extern const MCInstrDesc MipsInsts[];
1221 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1222 return MipsInsts[Opcode];
1225 static bool hasShortDelaySlot(unsigned Opcode) {
1228 case Mips::JALRS_MM:
1229 case Mips::JALRS16_MM:
1230 case Mips::BGEZALS_MM:
1231 case Mips::BLTZALS_MM:
1238 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1239 SmallVectorImpl<MCInst> &Instructions) {
1240 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1244 if (MCID.isBranch() || MCID.isCall()) {
1245 const unsigned Opcode = Inst.getOpcode();
1255 assert(hasCnMips() && "instruction only valid for octeon cpus");
1262 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1263 Offset = Inst.getOperand(2);
1264 if (!Offset.isImm())
1265 break; // We'll deal with this situation later on when applying fixups.
1266 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1267 return Error(IDLoc, "branch target out of range");
1268 if (OffsetToAlignment(Offset.getImm(),
1269 1LL << (inMicroMipsMode() ? 1 : 2)))
1270 return Error(IDLoc, "branch to misaligned address");
1284 case Mips::BGEZAL_MM:
1285 case Mips::BLTZAL_MM:
1288 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1289 Offset = Inst.getOperand(1);
1290 if (!Offset.isImm())
1291 break; // We'll deal with this situation later on when applying fixups.
1292 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1293 return Error(IDLoc, "branch target out of range");
1294 if (OffsetToAlignment(Offset.getImm(),
1295 1LL << (inMicroMipsMode() ? 1 : 2)))
1296 return Error(IDLoc, "branch to misaligned address");
1298 case Mips::BEQZ16_MM:
1299 case Mips::BNEZ16_MM:
1300 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1301 Offset = Inst.getOperand(1);
1302 if (!Offset.isImm())
1303 break; // We'll deal with this situation later on when applying fixups.
1304 if (!isIntN(8, Offset.getImm()))
1305 return Error(IDLoc, "branch target out of range");
1306 if (OffsetToAlignment(Offset.getImm(), 2LL))
1307 return Error(IDLoc, "branch to misaligned address");
1312 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1313 // We still accept it but it is a normal nop.
1314 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1315 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1316 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1321 const unsigned Opcode = Inst.getOpcode();
1333 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1334 // The offset is handled above
1335 Opnd = Inst.getOperand(1);
1337 return Error(IDLoc, "expected immediate operand kind");
1338 Imm = Opnd.getImm();
1339 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1340 Opcode == Mips::BBIT1 ? 63 : 31))
1341 return Error(IDLoc, "immediate operand value out of range");
1343 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1345 Inst.getOperand(1).setImm(Imm - 32);
1353 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1355 Opnd = Inst.getOperand(3);
1357 return Error(IDLoc, "expected immediate operand kind");
1358 Imm = Opnd.getImm();
1359 if (Imm < 0 || Imm > 31)
1360 return Error(IDLoc, "immediate operand value out of range");
1362 Opnd = Inst.getOperand(2);
1364 return Error(IDLoc, "expected immediate operand kind");
1365 Imm = Opnd.getImm();
1366 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1367 Opcode == Mips::EXTS ? 63 : 31))
1368 return Error(IDLoc, "immediate operand value out of range");
1370 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1371 Inst.getOperand(2).setImm(Imm - 32);
1377 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1378 Opnd = Inst.getOperand(2);
1380 return Error(IDLoc, "expected immediate operand kind");
1381 Imm = Opnd.getImm();
1382 if (!isInt<10>(Imm))
1383 return Error(IDLoc, "immediate operand value out of range");
1388 if (MCID.mayLoad() || MCID.mayStore()) {
1389 // Check the offset of memory operand, if it is a symbol
1390 // reference or immediate we may have to expand instructions.
1391 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1392 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1393 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1394 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1395 MCOperand &Op = Inst.getOperand(i);
1397 int MemOffset = Op.getImm();
1398 if (MemOffset < -32768 || MemOffset > 32767) {
1399 // Offset can't exceed 16bit value.
1400 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1403 } else if (Op.isExpr()) {
1404 const MCExpr *Expr = Op.getExpr();
1405 if (Expr->getKind() == MCExpr::SymbolRef) {
1406 const MCSymbolRefExpr *SR =
1407 static_cast<const MCSymbolRefExpr *>(Expr);
1408 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1410 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1413 } else if (!isEvaluated(Expr)) {
1414 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1422 if (inMicroMipsMode()) {
1423 if (MCID.mayLoad()) {
1424 // Try to create 16-bit GP relative load instruction.
1425 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1426 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1427 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1428 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1429 MCOperand &Op = Inst.getOperand(i);
1431 int MemOffset = Op.getImm();
1432 MCOperand &DstReg = Inst.getOperand(0);
1433 MCOperand &BaseReg = Inst.getOperand(1);
1434 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1435 getContext().getRegisterInfo()->getRegClass(
1436 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1437 BaseReg.getReg() == Mips::GP) {
1439 TmpInst.setLoc(IDLoc);
1440 TmpInst.setOpcode(Mips::LWGP_MM);
1441 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1442 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1443 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1444 Instructions.push_back(TmpInst);
1452 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1457 switch (Inst.getOpcode()) {
1460 case Mips::ADDIUS5_MM:
1461 Opnd = Inst.getOperand(2);
1463 return Error(IDLoc, "expected immediate operand kind");
1464 Imm = Opnd.getImm();
1465 if (Imm < -8 || Imm > 7)
1466 return Error(IDLoc, "immediate operand value out of range");
1468 case Mips::ADDIUSP_MM:
1469 Opnd = Inst.getOperand(0);
1471 return Error(IDLoc, "expected immediate operand kind");
1472 Imm = Opnd.getImm();
1473 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1475 return Error(IDLoc, "immediate operand value out of range");
1477 case Mips::SLL16_MM:
1478 case Mips::SRL16_MM:
1479 Opnd = Inst.getOperand(2);
1481 return Error(IDLoc, "expected immediate operand kind");
1482 Imm = Opnd.getImm();
1483 if (Imm < 1 || Imm > 8)
1484 return Error(IDLoc, "immediate operand value out of range");
1487 Opnd = Inst.getOperand(1);
1489 return Error(IDLoc, "expected immediate operand kind");
1490 Imm = Opnd.getImm();
1491 if (Imm < -1 || Imm > 126)
1492 return Error(IDLoc, "immediate operand value out of range");
1494 case Mips::ADDIUR2_MM:
1495 Opnd = Inst.getOperand(2);
1497 return Error(IDLoc, "expected immediate operand kind");
1498 Imm = Opnd.getImm();
1499 if (!(Imm == 1 || Imm == -1 ||
1500 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1501 return Error(IDLoc, "immediate operand value out of range");
1503 case Mips::ADDIUR1SP_MM:
1504 Opnd = Inst.getOperand(1);
1506 return Error(IDLoc, "expected immediate operand kind");
1507 Imm = Opnd.getImm();
1508 if (OffsetToAlignment(Imm, 4LL))
1509 return Error(IDLoc, "misaligned immediate operand value");
1510 if (Imm < 0 || Imm > 255)
1511 return Error(IDLoc, "immediate operand value out of range");
1513 case Mips::ANDI16_MM:
1514 Opnd = Inst.getOperand(2);
1516 return Error(IDLoc, "expected immediate operand kind");
1517 Imm = Opnd.getImm();
1518 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1519 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1520 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1521 return Error(IDLoc, "immediate operand value out of range");
1523 case Mips::LBU16_MM:
1524 Opnd = Inst.getOperand(2);
1526 return Error(IDLoc, "expected immediate operand kind");
1527 Imm = Opnd.getImm();
1528 if (Imm < -1 || Imm > 14)
1529 return Error(IDLoc, "immediate operand value out of range");
1532 Opnd = Inst.getOperand(2);
1534 return Error(IDLoc, "expected immediate operand kind");
1535 Imm = Opnd.getImm();
1536 if (Imm < 0 || Imm > 15)
1537 return Error(IDLoc, "immediate operand value out of range");
1539 case Mips::LHU16_MM:
1541 Opnd = Inst.getOperand(2);
1543 return Error(IDLoc, "expected immediate operand kind");
1544 Imm = Opnd.getImm();
1545 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1546 return Error(IDLoc, "immediate operand value out of range");
1550 Opnd = Inst.getOperand(2);
1552 return Error(IDLoc, "expected immediate operand kind");
1553 Imm = Opnd.getImm();
1554 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1555 return Error(IDLoc, "immediate operand value out of range");
1559 Opnd = Inst.getOperand(2);
1561 return Error(IDLoc, "expected immediate operand kind");
1562 Imm = Opnd.getImm();
1563 if (!isUInt<5>(Imm))
1564 return Error(IDLoc, "immediate operand value out of range");
1566 case Mips::ADDIUPC_MM:
1567 MCOperand Opnd = Inst.getOperand(1);
1569 return Error(IDLoc, "expected immediate operand kind");
1570 int Imm = Opnd.getImm();
1571 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1572 return Error(IDLoc, "immediate operand value out of range");
1577 if (needsExpansion(Inst)) {
1578 if (expandInstruction(Inst, IDLoc, Instructions))
1581 Instructions.push_back(Inst);
1583 // If this instruction has a delay slot and .set reorder is active,
1584 // emit a NOP after it.
1585 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1586 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1591 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1593 switch (Inst.getOpcode()) {
1594 case Mips::LoadImm32:
1595 case Mips::LoadImm64:
1596 case Mips::LoadAddrImm32:
1597 case Mips::LoadAddrReg32:
1598 case Mips::B_MM_Pseudo:
1601 case Mips::JalOneReg:
1602 case Mips::JalTwoReg:
1609 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1610 SmallVectorImpl<MCInst> &Instructions) {
1611 switch (Inst.getOpcode()) {
1612 default: llvm_unreachable("unimplemented expansion");
1613 case Mips::LoadImm32:
1614 return expandLoadImm(Inst, true, IDLoc, Instructions);
1615 case Mips::LoadImm64:
1616 return expandLoadImm(Inst, false, IDLoc, Instructions);
1617 case Mips::LoadAddrImm32:
1618 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1619 case Mips::LoadAddrReg32:
1620 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1621 case Mips::B_MM_Pseudo:
1622 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1625 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1626 case Mips::JalOneReg:
1627 case Mips::JalTwoReg:
1628 return expandJalWithRegs(Inst, IDLoc, Instructions);
1633 template <unsigned ShiftAmount>
1634 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1635 SmallVectorImpl<MCInst> &Instructions) {
1637 if (ShiftAmount >= 32) {
1638 tmpInst.setOpcode(Mips::DSLL32);
1639 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1640 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1641 tmpInst.addOperand(MCOperand::CreateImm(ShiftAmount - 32));
1642 tmpInst.setLoc(IDLoc);
1643 Instructions.push_back(tmpInst);
1645 } else if (ShiftAmount > 0) {
1646 tmpInst.setOpcode(Mips::DSLL);
1647 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1648 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1649 tmpInst.addOperand(MCOperand::CreateImm(ShiftAmount));
1650 tmpInst.setLoc(IDLoc);
1651 Instructions.push_back(tmpInst);
1654 // There's no need for an ORi if the immediate is 0.
1655 if (Operand.isImm() && Operand.getImm() == 0)
1658 tmpInst.setOpcode(Mips::ORi);
1659 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1660 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1661 tmpInst.addOperand(Operand);
1662 tmpInst.setLoc(IDLoc);
1663 Instructions.push_back(tmpInst);
1666 template <unsigned ShiftAmount>
1667 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1668 SmallVectorImpl<MCInst> &Instructions) {
1669 createLShiftOri<ShiftAmount>(MCOperand::CreateImm(Value), RegNo, IDLoc,
1674 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1675 SmallVectorImpl<MCInst> &Instructions) {
1676 // Create a JALR instruction which is going to replace the pseudo-JAL.
1678 JalrInst.setLoc(IDLoc);
1679 const MCOperand FirstRegOp = Inst.getOperand(0);
1680 const unsigned Opcode = Inst.getOpcode();
1682 if (Opcode == Mips::JalOneReg) {
1683 // jal $rs => jalr $rs
1684 if (inMicroMipsMode()) {
1685 JalrInst.setOpcode(Mips::JALR16_MM);
1686 JalrInst.addOperand(FirstRegOp);
1688 JalrInst.setOpcode(Mips::JALR);
1689 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1690 JalrInst.addOperand(FirstRegOp);
1692 } else if (Opcode == Mips::JalTwoReg) {
1693 // jal $rd, $rs => jalr $rd, $rs
1694 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1695 JalrInst.addOperand(FirstRegOp);
1696 const MCOperand SecondRegOp = Inst.getOperand(1);
1697 JalrInst.addOperand(SecondRegOp);
1699 Instructions.push_back(JalrInst);
1701 // If .set reorder is active, emit a NOP after it.
1702 if (AssemblerOptions.back()->isReorder()) {
1703 // This is a 32-bit NOP because these 2 pseudo-instructions
1704 // do not have a short delay slot.
1706 NopInst.setOpcode(Mips::SLL);
1707 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1708 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1709 NopInst.addOperand(MCOperand::CreateImm(0));
1710 Instructions.push_back(NopInst);
1716 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1717 SmallVectorImpl<MCInst> &Instructions) {
1718 if (!Is32BitImm && !isGP64bit()) {
1719 Error(IDLoc, "instruction requires a 64-bit architecture");
1724 const MCOperand &ImmOp = Inst.getOperand(1);
1725 assert(ImmOp.isImm() && "expected immediate operand kind");
1726 const MCOperand &RegOp = Inst.getOperand(0);
1727 assert(RegOp.isReg() && "expected register operand kind");
1729 int64_t ImmValue = ImmOp.getImm();
1730 unsigned Reg = RegOp.getReg();
1731 tmpInst.setLoc(IDLoc);
1732 // FIXME: gas has a special case for values that are 000...1111, which
1733 // becomes a li -1 and then a dsrl
1734 if (0 <= ImmValue && ImmValue <= 65535) {
1735 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1736 // li d,j => ori d,$zero,j
1737 tmpInst.setOpcode(Mips::ORi);
1738 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1739 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1740 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1741 Instructions.push_back(tmpInst);
1742 } else if (ImmValue < 0 && ImmValue >= -32768) {
1743 // For negative signed 16-bit values (-32768 <= j < 0):
1744 // li d,j => addiu d,$zero,j
1745 tmpInst.setOpcode(Mips::ADDiu);
1746 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1747 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1748 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1749 Instructions.push_back(tmpInst);
1750 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1751 // For all other values which are representable as a 32-bit integer:
1752 // li d,j => lui d,hi16(j)
1754 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1755 uint16_t Bits15To0 = ImmValue & 0xffff;
1757 tmpInst.setOpcode(Mips::LUi);
1758 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1759 tmpInst.addOperand(MCOperand::CreateImm(Bits31To16));
1760 Instructions.push_back(tmpInst);
1761 createLShiftOri<0>(Bits15To0, Reg, IDLoc, Instructions);
1762 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1764 Error(IDLoc, "instruction requires a 32-bit immediate");
1768 // <------- lo32 ------>
1769 // <------- hi32 ------>
1770 // <- hi16 -> <- lo16 ->
1771 // _________________________________
1773 // | 16-bits | 16-bits | 16-bits |
1774 // |__________|__________|__________|
1776 // For any 64-bit value that is representable as a 48-bit integer:
1777 // li d,j => lui d,hi16(j)
1778 // ori d,d,hi16(lo32(j))
1780 // ori d,d,lo16(lo32(j))
1781 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1782 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1783 uint16_t Bits15To0 = ImmValue & 0xffff;
1785 tmpInst.setOpcode(Mips::LUi);
1786 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1787 tmpInst.addOperand(MCOperand::CreateImm(Bits47To32));
1788 Instructions.push_back(tmpInst);
1789 createLShiftOri<0>(Bits31To16, Reg, IDLoc, Instructions);
1790 createLShiftOri<16>(Bits15To0, Reg, IDLoc, Instructions);
1793 Error(IDLoc, "instruction requires a 32-bit immediate");
1797 // <------- hi32 ------> <------- lo32 ------>
1798 // <- hi16 -> <- lo16 ->
1799 // ___________________________________________
1801 // | 16-bits | 16-bits | 16-bits | 16-bits |
1802 // |__________|__________|__________|__________|
1804 // For all other values which are representable as a 64-bit integer:
1805 // li d,j => lui d,hi16(j)
1806 // ori d,d,lo16(hi32(j))
1808 // ori d,d,hi16(lo32(j))
1810 // ori d,d,lo16(lo32(j))
1811 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1812 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1813 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1814 uint16_t Bits15To0 = ImmValue & 0xffff;
1816 tmpInst.setOpcode(Mips::LUi);
1817 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1818 tmpInst.addOperand(MCOperand::CreateImm(Bits63To48));
1819 Instructions.push_back(tmpInst);
1820 createLShiftOri<0>(Bits47To32, Reg, IDLoc, Instructions);
1822 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1823 // two left shifts of 16 bits.
1824 if (Bits31To16 == 0) {
1825 createLShiftOri<32>(Bits15To0, Reg, IDLoc, Instructions);
1827 createLShiftOri<16>(Bits31To16, Reg, IDLoc, Instructions);
1828 createLShiftOri<16>(Bits15To0, Reg, IDLoc, Instructions);
1835 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1836 SmallVectorImpl<MCInst> &Instructions) {
1838 const MCOperand &ImmOp = Inst.getOperand(2);
1839 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1840 "expected immediate operand kind");
1841 if (!ImmOp.isImm()) {
1842 expandLoadAddressSym(Inst, IDLoc, Instructions);
1845 const MCOperand &SrcRegOp = Inst.getOperand(1);
1846 assert(SrcRegOp.isReg() && "expected register operand kind");
1847 const MCOperand &DstRegOp = Inst.getOperand(0);
1848 assert(DstRegOp.isReg() && "expected register operand kind");
1849 int ImmValue = ImmOp.getImm();
1850 if (-32768 <= ImmValue && ImmValue <= 65535) {
1851 // For -32768 <= j <= 65535.
1852 // la d,j(s) => addiu d,s,j
1853 tmpInst.setOpcode(Mips::ADDiu);
1854 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1855 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1856 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1857 Instructions.push_back(tmpInst);
1859 // For any other value of j that is representable as a 32-bit integer.
1860 // la d,j(s) => lui d,hi16(j)
1863 tmpInst.setOpcode(Mips::LUi);
1864 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1865 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1866 Instructions.push_back(tmpInst);
1868 tmpInst.setOpcode(Mips::ORi);
1869 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1870 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1871 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1872 Instructions.push_back(tmpInst);
1874 tmpInst.setOpcode(Mips::ADDu);
1875 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1876 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1877 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1878 Instructions.push_back(tmpInst);
1884 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1885 SmallVectorImpl<MCInst> &Instructions) {
1887 const MCOperand &ImmOp = Inst.getOperand(1);
1888 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1889 "expected immediate operand kind");
1890 if (!ImmOp.isImm()) {
1891 expandLoadAddressSym(Inst, IDLoc, Instructions);
1894 const MCOperand &RegOp = Inst.getOperand(0);
1895 assert(RegOp.isReg() && "expected register operand kind");
1896 int ImmValue = ImmOp.getImm();
1897 if (-32768 <= ImmValue && ImmValue <= 65535) {
1898 // For -32768 <= j <= 65535.
1899 // la d,j => addiu d,$zero,j
1900 tmpInst.setOpcode(Mips::ADDiu);
1901 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1902 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1903 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1904 Instructions.push_back(tmpInst);
1906 // For any other value of j that is representable as a 32-bit integer.
1907 // la d,j => lui d,hi16(j)
1909 tmpInst.setOpcode(Mips::LUi);
1910 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1911 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1912 Instructions.push_back(tmpInst);
1914 tmpInst.setOpcode(Mips::ORi);
1915 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1916 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1917 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1918 Instructions.push_back(tmpInst);
1924 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1925 SmallVectorImpl<MCInst> &Instructions) {
1926 // FIXME: If we do have a valid at register to use, we should generate a
1927 // slightly shorter sequence here.
1929 int ExprOperandNo = 1;
1930 // Sometimes the assembly parser will get the immediate expression as
1931 // a $zero + an immediate.
1932 if (Inst.getNumOperands() == 3) {
1933 assert(Inst.getOperand(1).getReg() ==
1934 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1937 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1938 assert(SymOp.isExpr() && "expected symbol operand kind");
1939 const MCOperand &RegOp = Inst.getOperand(0);
1940 unsigned RegNo = RegOp.getReg();
1941 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1942 const MCSymbolRefExpr *HiExpr =
1943 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1944 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1945 const MCSymbolRefExpr *LoExpr =
1946 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1947 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1949 // If it's a 64-bit architecture, expand to:
1950 // la d,sym => lui d,highest(sym)
1951 // ori d,d,higher(sym)
1953 // ori d,d,hi16(sym)
1955 // ori d,d,lo16(sym)
1956 const MCSymbolRefExpr *HighestExpr =
1957 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1958 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1959 const MCSymbolRefExpr *HigherExpr =
1960 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1961 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1963 tmpInst.setOpcode(Mips::LUi);
1964 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1965 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1966 Instructions.push_back(tmpInst);
1968 createLShiftOri<0>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1970 createLShiftOri<16>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1972 createLShiftOri<16>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1975 // Otherwise, expand to:
1976 // la d,sym => lui d,hi16(sym)
1977 // ori d,d,lo16(sym)
1978 tmpInst.setOpcode(Mips::LUi);
1979 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1980 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1981 Instructions.push_back(tmpInst);
1983 createLShiftOri<0>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1988 bool MipsAsmParser::expandUncondBranchMMPseudo(
1989 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1990 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1991 "unexpected number of operands");
1993 MCOperand Offset = Inst.getOperand(0);
1994 if (Offset.isExpr()) {
1996 Inst.setOpcode(Mips::BEQ_MM);
1997 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1998 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1999 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
2001 assert(Offset.isImm() && "expected immediate operand kind");
2002 if (isIntN(11, Offset.getImm())) {
2003 // If offset fits into 11 bits then this instruction becomes microMIPS
2004 // 16-bit unconditional branch instruction.
2005 Inst.setOpcode(Mips::B16_MM);
2007 if (!isIntN(17, Offset.getImm()))
2008 Error(IDLoc, "branch target out of range");
2009 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2010 Error(IDLoc, "branch to misaligned address");
2012 Inst.setOpcode(Mips::BEQ_MM);
2013 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2014 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2015 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
2018 Instructions.push_back(Inst);
2020 // If .set reorder is active, emit a NOP after the branch instruction.
2021 if (AssemblerOptions.back()->isReorder())
2022 createNop(true, IDLoc, Instructions);
2027 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2028 SmallVectorImpl<MCInst> &Instructions,
2029 bool isLoad, bool isImmOpnd) {
2030 const MCSymbolRefExpr *SR;
2032 unsigned ImmOffset, HiOffset, LoOffset;
2033 const MCExpr *ExprOffset;
2035 // 1st operand is either the source or destination register.
2036 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2037 unsigned RegOpNum = Inst.getOperand(0).getReg();
2038 // 2nd operand is the base register.
2039 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2040 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2041 // 3rd operand is either an immediate or expression.
2043 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2044 ImmOffset = Inst.getOperand(2).getImm();
2045 LoOffset = ImmOffset & 0x0000ffff;
2046 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2047 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2048 if (LoOffset & 0x8000)
2051 ExprOffset = Inst.getOperand(2).getExpr();
2052 // All instructions will have the same location.
2053 TempInst.setLoc(IDLoc);
2054 // These are some of the types of expansions we perform here:
2055 // 1) lw $8, sym => lui $8, %hi(sym)
2056 // lw $8, %lo(sym)($8)
2057 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2059 // lw $8, %lo(offset)($9)
2060 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2062 // lw $8, %lo(offset)($at)
2063 // 4) sw $8, sym => lui $at, %hi(sym)
2064 // sw $8, %lo(sym)($at)
2065 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2067 // sw $8, %lo(offset)($at)
2068 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2069 // ldc1 $f0, %lo(sym)($at)
2071 // For load instructions we can use the destination register as a temporary
2072 // if base and dst are different (examples 1 and 2) and if the base register
2073 // is general purpose otherwise we must use $at (example 6) and error if it's
2074 // not available. For stores we must use $at (examples 4 and 5) because we
2075 // must not clobber the source register setting up the offset.
2076 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2077 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2078 unsigned RegClassIDOp0 =
2079 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2080 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2081 (RegClassIDOp0 == Mips::GPR64RegClassID);
2082 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2083 TmpRegNum = RegOpNum;
2085 // At this point we need AT to perform the expansions and we exit if it is
2087 TmpRegNum = getATReg(IDLoc);
2092 TempInst.setOpcode(Mips::LUi);
2093 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2095 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2097 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2098 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2099 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2100 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2102 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2104 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2105 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2108 // Add the instruction to the list.
2109 Instructions.push_back(TempInst);
2110 // Prepare TempInst for next instruction.
2112 // Add temp register to base.
2113 if (BaseRegNum != Mips::ZERO) {
2114 TempInst.setOpcode(Mips::ADDu);
2115 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2116 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2117 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2118 Instructions.push_back(TempInst);
2121 // And finally, create original instruction with low part
2122 // of offset and new base.
2123 TempInst.setOpcode(Inst.getOpcode());
2124 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2125 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2127 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2129 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2130 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2131 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2133 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2135 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2136 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2139 Instructions.push_back(TempInst);
2144 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2145 SmallVectorImpl<MCInst> &Instructions) {
2146 unsigned OpNum = Inst.getNumOperands();
2147 unsigned Opcode = Inst.getOpcode();
2148 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2150 assert (Inst.getOperand(OpNum - 1).isImm() &&
2151 Inst.getOperand(OpNum - 2).isReg() &&
2152 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2154 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2155 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2156 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2157 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2158 // It can be implemented as SWM16 or LWM16 instruction.
2159 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2161 Inst.setOpcode(NewOpcode);
2162 Instructions.push_back(Inst);
2166 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2167 SmallVectorImpl<MCInst> &Instructions) {
2169 if (hasShortDelaySlot) {
2170 NopInst.setOpcode(Mips::MOVE16_MM);
2171 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2172 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2174 NopInst.setOpcode(Mips::SLL);
2175 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2176 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2177 NopInst.addOperand(MCOperand::CreateImm(0));
2179 Instructions.push_back(NopInst);
2182 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2183 // As described by the Mips32r2 spec, the registers Rd and Rs for
2184 // jalr.hb must be different.
2185 unsigned Opcode = Inst.getOpcode();
2187 if (Opcode == Mips::JALR_HB &&
2188 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2189 return Match_RequiresDifferentSrcAndDst;
2191 return Match_Success;
2194 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2195 OperandVector &Operands,
2197 uint64_t &ErrorInfo,
2198 bool MatchingInlineAsm) {
2201 SmallVector<MCInst, 8> Instructions;
2202 unsigned MatchResult =
2203 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2205 switch (MatchResult) {
2206 case Match_Success: {
2207 if (processInstruction(Inst, IDLoc, Instructions))
2209 for (unsigned i = 0; i < Instructions.size(); i++)
2210 Out.EmitInstruction(Instructions[i], STI);
2213 case Match_MissingFeature:
2214 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2216 case Match_InvalidOperand: {
2217 SMLoc ErrorLoc = IDLoc;
2218 if (ErrorInfo != ~0ULL) {
2219 if (ErrorInfo >= Operands.size())
2220 return Error(IDLoc, "too few operands for instruction");
2222 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2223 if (ErrorLoc == SMLoc())
2227 return Error(ErrorLoc, "invalid operand for instruction");
2229 case Match_MnemonicFail:
2230 return Error(IDLoc, "invalid instruction");
2231 case Match_RequiresDifferentSrcAndDst:
2232 return Error(IDLoc, "source and destination must be different");
2235 llvm_unreachable("Implement any new match types added!");
2238 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2239 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2240 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2241 ") without \".set noat\"");
2245 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2246 SMRange Range, bool ShowColors) {
2247 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2248 Range, SMFixIt(Range, FixMsg),
2252 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2255 CC = StringSwitch<unsigned>(Name)
2291 if (!(isABI_N32() || isABI_N64()))
2294 if (12 <= CC && CC <= 15) {
2295 // Name is one of t4-t7
2296 AsmToken RegTok = getLexer().peekTok();
2297 SMRange RegRange = RegTok.getLocRange();
2299 StringRef FixedName = StringSwitch<StringRef>(Name)
2305 assert(FixedName != "" && "Register name is not one of t4-t7.");
2307 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2308 "Did you mean $" + FixedName + "?", RegRange);
2311 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2312 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2313 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2314 if (8 <= CC && CC <= 11)
2318 CC = StringSwitch<unsigned>(Name)
2330 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2333 CC = StringSwitch<unsigned>(Name)
2334 .Case("hwr_cpunum", 0)
2335 .Case("hwr_synci_step", 1)
2337 .Case("hwr_ccres", 3)
2338 .Case("hwr_ulr", 29)
2344 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2346 if (Name[0] == 'f') {
2347 StringRef NumString = Name.substr(1);
2349 if (NumString.getAsInteger(10, IntVal))
2350 return -1; // This is not an integer.
2351 if (IntVal > 31) // Maximum index for fpu register.
2358 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2360 if (Name.startswith("fcc")) {
2361 StringRef NumString = Name.substr(3);
2363 if (NumString.getAsInteger(10, IntVal))
2364 return -1; // This is not an integer.
2365 if (IntVal > 7) // There are only 8 fcc registers.
2372 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2374 if (Name.startswith("ac")) {
2375 StringRef NumString = Name.substr(2);
2377 if (NumString.getAsInteger(10, IntVal))
2378 return -1; // This is not an integer.
2379 if (IntVal > 3) // There are only 3 acc registers.
2386 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2389 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2398 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2401 CC = StringSwitch<unsigned>(Name)
2404 .Case("msaaccess", 2)
2406 .Case("msamodify", 4)
2407 .Case("msarequest", 5)
2409 .Case("msaunmap", 7)
2415 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2416 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2418 reportParseError(Loc,
2419 "pseudo-instruction requires $at, which is not available");
2422 unsigned AT = getReg(
2423 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2427 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2428 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2431 unsigned MipsAsmParser::getGPR(int RegNo) {
2432 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2436 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2438 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2441 return getReg(RegClass, RegNum);
2444 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2445 MCAsmParser &Parser = getParser();
2446 DEBUG(dbgs() << "parseOperand\n");
2448 // Check if the current operand has a custom associated parser, if so, try to
2449 // custom parse the operand, or fallback to the general approach.
2450 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2451 if (ResTy == MatchOperand_Success)
2453 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2454 // there was a match, but an error occurred, in which case, just return that
2455 // the operand parsing failed.
2456 if (ResTy == MatchOperand_ParseFail)
2459 DEBUG(dbgs() << ".. Generic Parser\n");
2461 switch (getLexer().getKind()) {
2463 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2465 case AsmToken::Dollar: {
2466 // Parse the register.
2467 SMLoc S = Parser.getTok().getLoc();
2469 // Almost all registers have been parsed by custom parsers. There is only
2470 // one exception to this. $zero (and it's alias $0) will reach this point
2471 // for div, divu, and similar instructions because it is not an operand
2472 // to the instruction definition but an explicit register. Special case
2473 // this situation for now.
2474 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2477 // Maybe it is a symbol reference.
2478 StringRef Identifier;
2479 if (Parser.parseIdentifier(Identifier))
2482 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2483 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2484 // Otherwise create a symbol reference.
2486 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2488 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2491 // Else drop to expression parsing.
2492 case AsmToken::LParen:
2493 case AsmToken::Minus:
2494 case AsmToken::Plus:
2495 case AsmToken::Integer:
2496 case AsmToken::Tilde:
2497 case AsmToken::String: {
2498 DEBUG(dbgs() << ".. generic integer\n");
2499 OperandMatchResultTy ResTy = parseImm(Operands);
2500 return ResTy != MatchOperand_Success;
2502 case AsmToken::Percent: {
2503 // It is a symbol reference or constant expression.
2504 const MCExpr *IdVal;
2505 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2506 if (parseRelocOperand(IdVal))
2509 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2511 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2513 } // case AsmToken::Percent
2514 } // switch(getLexer().getKind())
2518 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2519 StringRef RelocStr) {
2521 // Check the type of the expression.
2522 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2523 // It's a constant, evaluate reloc value.
2525 switch (getVariantKind(RelocStr)) {
2526 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2527 // Get the 1st 16-bits.
2528 Val = MCE->getValue() & 0xffff;
2530 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2531 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2532 // 16 bits being negative.
2533 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2535 case MCSymbolRefExpr::VK_Mips_HIGHER:
2536 // Get the 3rd 16-bits.
2537 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2539 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2540 // Get the 4th 16-bits.
2541 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2544 report_fatal_error("unsupported reloc value");
2546 return MCConstantExpr::Create(Val, getContext());
2549 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2550 // It's a symbol, create a symbolic expression from the symbol.
2551 StringRef Symbol = MSRE->getSymbol().getName();
2552 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2553 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2557 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2558 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2560 // Try to create target expression.
2561 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2562 return MipsMCExpr::Create(VK, Expr, getContext());
2564 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2565 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2566 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2570 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2571 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2572 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2575 // Just return the original expression.
2579 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2581 switch (Expr->getKind()) {
2582 case MCExpr::Constant:
2584 case MCExpr::SymbolRef:
2585 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2586 case MCExpr::Binary:
2587 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2588 if (!isEvaluated(BE->getLHS()))
2590 return isEvaluated(BE->getRHS());
2593 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2594 case MCExpr::Target:
2600 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2601 MCAsmParser &Parser = getParser();
2602 Parser.Lex(); // Eat the % token.
2603 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2604 if (Tok.isNot(AsmToken::Identifier))
2607 std::string Str = Tok.getIdentifier();
2609 Parser.Lex(); // Eat the identifier.
2610 // Now make an expression from the rest of the operand.
2611 const MCExpr *IdVal;
2614 if (getLexer().getKind() == AsmToken::LParen) {
2616 Parser.Lex(); // Eat the '(' token.
2617 if (getLexer().getKind() == AsmToken::Percent) {
2618 Parser.Lex(); // Eat the % token.
2619 const AsmToken &nextTok = Parser.getTok();
2620 if (nextTok.isNot(AsmToken::Identifier))
2623 Str += nextTok.getIdentifier();
2624 Parser.Lex(); // Eat the identifier.
2625 if (getLexer().getKind() != AsmToken::LParen)
2630 if (getParser().parseParenExpression(IdVal, EndLoc))
2633 while (getLexer().getKind() == AsmToken::RParen)
2634 Parser.Lex(); // Eat the ')' token.
2637 return true; // Parenthesis must follow the relocation operand.
2639 Res = evaluateRelocExpr(IdVal, Str);
2643 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2645 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2646 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2647 if (ResTy == MatchOperand_Success) {
2648 assert(Operands.size() == 1);
2649 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2650 StartLoc = Operand.getStartLoc();
2651 EndLoc = Operand.getEndLoc();
2653 // AFAIK, we only support numeric registers and named GPR's in CFI
2655 // Don't worry about eating tokens before failing. Using an unrecognised
2656 // register is a parse error.
2657 if (Operand.isGPRAsmReg()) {
2658 // Resolve to GPR32 or GPR64 appropriately.
2659 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2662 return (RegNo == (unsigned)-1);
2665 assert(Operands.size() == 0);
2666 return (RegNo == (unsigned)-1);
2669 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2670 MCAsmParser &Parser = getParser();
2674 while (getLexer().getKind() == AsmToken::LParen)
2677 switch (getLexer().getKind()) {
2680 case AsmToken::Identifier:
2681 case AsmToken::LParen:
2682 case AsmToken::Integer:
2683 case AsmToken::Minus:
2684 case AsmToken::Plus:
2686 Result = getParser().parseParenExpression(Res, S);
2688 Result = (getParser().parseExpression(Res));
2689 while (getLexer().getKind() == AsmToken::RParen)
2692 case AsmToken::Percent:
2693 Result = parseRelocOperand(Res);
2698 MipsAsmParser::OperandMatchResultTy
2699 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2700 MCAsmParser &Parser = getParser();
2701 DEBUG(dbgs() << "parseMemOperand\n");
2702 const MCExpr *IdVal = nullptr;
2704 bool isParenExpr = false;
2705 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2706 // First operand is the offset.
2707 S = Parser.getTok().getLoc();
2709 if (getLexer().getKind() == AsmToken::LParen) {
2714 if (getLexer().getKind() != AsmToken::Dollar) {
2715 if (parseMemOffset(IdVal, isParenExpr))
2716 return MatchOperand_ParseFail;
2718 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2719 if (Tok.isNot(AsmToken::LParen)) {
2720 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2721 if (Mnemonic.getToken() == "la") {
2723 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2724 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2725 return MatchOperand_Success;
2727 if (Tok.is(AsmToken::EndOfStatement)) {
2729 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2731 // Zero register assumed, add a memory operand with ZERO as its base.
2732 // "Base" will be managed by k_Memory.
2733 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2736 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2737 return MatchOperand_Success;
2739 Error(Parser.getTok().getLoc(), "'(' expected");
2740 return MatchOperand_ParseFail;
2743 Parser.Lex(); // Eat the '(' token.
2746 Res = parseAnyRegister(Operands);
2747 if (Res != MatchOperand_Success)
2750 if (Parser.getTok().isNot(AsmToken::RParen)) {
2751 Error(Parser.getTok().getLoc(), "')' expected");
2752 return MatchOperand_ParseFail;
2755 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2757 Parser.Lex(); // Eat the ')' token.
2760 IdVal = MCConstantExpr::Create(0, getContext());
2762 // Replace the register operand with the memory operand.
2763 std::unique_ptr<MipsOperand> op(
2764 static_cast<MipsOperand *>(Operands.back().release()));
2765 // Remove the register from the operands.
2766 // "op" will be managed by k_Memory.
2767 Operands.pop_back();
2768 // Add the memory operand.
2769 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2771 if (IdVal->EvaluateAsAbsolute(Imm))
2772 IdVal = MCConstantExpr::Create(Imm, getContext());
2773 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2774 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2778 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2779 return MatchOperand_Success;
2782 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2783 MCAsmParser &Parser = getParser();
2784 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2786 SMLoc S = Parser.getTok().getLoc();
2788 if (Sym->isVariable())
2789 Expr = Sym->getVariableValue();
2792 if (Expr->getKind() == MCExpr::SymbolRef) {
2793 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2794 StringRef DefSymbol = Ref->getSymbol().getName();
2795 if (DefSymbol.startswith("$")) {
2796 OperandMatchResultTy ResTy =
2797 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2798 if (ResTy == MatchOperand_Success) {
2801 } else if (ResTy == MatchOperand_ParseFail)
2802 llvm_unreachable("Should never ParseFail");
2805 } else if (Expr->getKind() == MCExpr::Constant) {
2807 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2809 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2816 MipsAsmParser::OperandMatchResultTy
2817 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2818 StringRef Identifier,
2820 int Index = matchCPURegisterName(Identifier);
2822 Operands.push_back(MipsOperand::createGPRReg(
2823 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2824 return MatchOperand_Success;
2827 Index = matchHWRegsRegisterName(Identifier);
2829 Operands.push_back(MipsOperand::createHWRegsReg(
2830 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2831 return MatchOperand_Success;
2834 Index = matchFPURegisterName(Identifier);
2836 Operands.push_back(MipsOperand::createFGRReg(
2837 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2838 return MatchOperand_Success;
2841 Index = matchFCCRegisterName(Identifier);
2843 Operands.push_back(MipsOperand::createFCCReg(
2844 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2845 return MatchOperand_Success;
2848 Index = matchACRegisterName(Identifier);
2850 Operands.push_back(MipsOperand::createACCReg(
2851 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2852 return MatchOperand_Success;
2855 Index = matchMSA128RegisterName(Identifier);
2857 Operands.push_back(MipsOperand::createMSA128Reg(
2858 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2859 return MatchOperand_Success;
2862 Index = matchMSA128CtrlRegisterName(Identifier);
2864 Operands.push_back(MipsOperand::createMSACtrlReg(
2865 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2866 return MatchOperand_Success;
2869 return MatchOperand_NoMatch;
2872 MipsAsmParser::OperandMatchResultTy
2873 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2874 MCAsmParser &Parser = getParser();
2875 auto Token = Parser.getLexer().peekTok(false);
2877 if (Token.is(AsmToken::Identifier)) {
2878 DEBUG(dbgs() << ".. identifier\n");
2879 StringRef Identifier = Token.getIdentifier();
2880 OperandMatchResultTy ResTy =
2881 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2883 } else if (Token.is(AsmToken::Integer)) {
2884 DEBUG(dbgs() << ".. integer\n");
2885 Operands.push_back(MipsOperand::createNumericReg(
2886 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2888 return MatchOperand_Success;
2891 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2893 return MatchOperand_NoMatch;
2896 MipsAsmParser::OperandMatchResultTy
2897 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2898 MCAsmParser &Parser = getParser();
2899 DEBUG(dbgs() << "parseAnyRegister\n");
2901 auto Token = Parser.getTok();
2903 SMLoc S = Token.getLoc();
2905 if (Token.isNot(AsmToken::Dollar)) {
2906 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2907 if (Token.is(AsmToken::Identifier)) {
2908 if (searchSymbolAlias(Operands))
2909 return MatchOperand_Success;
2911 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2912 return MatchOperand_NoMatch;
2914 DEBUG(dbgs() << ".. $\n");
2916 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2917 if (ResTy == MatchOperand_Success) {
2919 Parser.Lex(); // identifier
2924 MipsAsmParser::OperandMatchResultTy
2925 MipsAsmParser::parseImm(OperandVector &Operands) {
2926 MCAsmParser &Parser = getParser();
2927 switch (getLexer().getKind()) {
2929 return MatchOperand_NoMatch;
2930 case AsmToken::LParen:
2931 case AsmToken::Minus:
2932 case AsmToken::Plus:
2933 case AsmToken::Integer:
2934 case AsmToken::Tilde:
2935 case AsmToken::String:
2939 const MCExpr *IdVal;
2940 SMLoc S = Parser.getTok().getLoc();
2941 if (getParser().parseExpression(IdVal))
2942 return MatchOperand_ParseFail;
2944 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2945 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2946 return MatchOperand_Success;
2949 MipsAsmParser::OperandMatchResultTy
2950 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2951 MCAsmParser &Parser = getParser();
2952 DEBUG(dbgs() << "parseJumpTarget\n");
2954 SMLoc S = getLexer().getLoc();
2956 // Integers and expressions are acceptable
2957 OperandMatchResultTy ResTy = parseImm(Operands);
2958 if (ResTy != MatchOperand_NoMatch)
2961 // Registers are a valid target and have priority over symbols.
2962 ResTy = parseAnyRegister(Operands);
2963 if (ResTy != MatchOperand_NoMatch)
2966 const MCExpr *Expr = nullptr;
2967 if (Parser.parseExpression(Expr)) {
2968 // We have no way of knowing if a symbol was consumed so we must ParseFail
2969 return MatchOperand_ParseFail;
2972 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2973 return MatchOperand_Success;
2976 MipsAsmParser::OperandMatchResultTy
2977 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2978 MCAsmParser &Parser = getParser();
2979 const MCExpr *IdVal;
2980 // If the first token is '$' we may have register operand.
2981 if (Parser.getTok().is(AsmToken::Dollar))
2982 return MatchOperand_NoMatch;
2983 SMLoc S = Parser.getTok().getLoc();
2984 if (getParser().parseExpression(IdVal))
2985 return MatchOperand_ParseFail;
2986 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2987 assert(MCE && "Unexpected MCExpr type.");
2988 int64_t Val = MCE->getValue();
2989 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2990 Operands.push_back(MipsOperand::CreateImm(
2991 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2992 return MatchOperand_Success;
2995 MipsAsmParser::OperandMatchResultTy
2996 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2997 MCAsmParser &Parser = getParser();
2998 switch (getLexer().getKind()) {
3000 return MatchOperand_NoMatch;
3001 case AsmToken::LParen:
3002 case AsmToken::Plus:
3003 case AsmToken::Minus:
3004 case AsmToken::Integer:
3009 SMLoc S = Parser.getTok().getLoc();
3011 if (getParser().parseExpression(Expr))
3012 return MatchOperand_ParseFail;
3015 if (!Expr->EvaluateAsAbsolute(Val)) {
3016 Error(S, "expected immediate value");
3017 return MatchOperand_ParseFail;
3020 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3021 // and because the CPU always adds one to the immediate field, the allowed
3022 // range becomes 1..4. We'll only check the range here and will deal
3023 // with the addition/subtraction when actually decoding/encoding
3025 if (Val < 1 || Val > 4) {
3026 Error(S, "immediate not in range (1..4)");
3027 return MatchOperand_ParseFail;
3031 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3032 return MatchOperand_Success;
3035 MipsAsmParser::OperandMatchResultTy
3036 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3037 MCAsmParser &Parser = getParser();
3038 SmallVector<unsigned, 10> Regs;
3040 unsigned PrevReg = Mips::NoRegister;
3041 bool RegRange = false;
3042 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3044 if (Parser.getTok().isNot(AsmToken::Dollar))
3045 return MatchOperand_ParseFail;
3047 SMLoc S = Parser.getTok().getLoc();
3048 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3049 SMLoc E = getLexer().getLoc();
3050 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3051 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3053 // Remove last register operand because registers from register range
3054 // should be inserted first.
3055 if (RegNo == Mips::RA) {
3056 Regs.push_back(RegNo);
3058 unsigned TmpReg = PrevReg + 1;
3059 while (TmpReg <= RegNo) {
3060 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3061 Error(E, "invalid register operand");
3062 return MatchOperand_ParseFail;
3066 Regs.push_back(TmpReg++);
3072 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3073 (RegNo != Mips::RA)) {
3074 Error(E, "$16 or $31 expected");
3075 return MatchOperand_ParseFail;
3076 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3077 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3078 Error(E, "invalid register operand");
3079 return MatchOperand_ParseFail;
3080 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3081 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3082 Error(E, "consecutive register numbers expected");
3083 return MatchOperand_ParseFail;
3086 Regs.push_back(RegNo);
3089 if (Parser.getTok().is(AsmToken::Minus))
3092 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3093 !Parser.getTok().isNot(AsmToken::Comma)) {
3094 Error(E, "',' or '-' expected");
3095 return MatchOperand_ParseFail;
3098 Lex(); // Consume comma or minus
3099 if (Parser.getTok().isNot(AsmToken::Dollar))
3105 SMLoc E = Parser.getTok().getLoc();
3106 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3107 parseMemOperand(Operands);
3108 return MatchOperand_Success;
3111 MipsAsmParser::OperandMatchResultTy
3112 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3113 MCAsmParser &Parser = getParser();
3115 SMLoc S = Parser.getTok().getLoc();
3116 if (parseAnyRegister(Operands) != MatchOperand_Success)
3117 return MatchOperand_ParseFail;
3119 SMLoc E = Parser.getTok().getLoc();
3120 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3121 unsigned Reg = Op.getGPR32Reg();
3122 Operands.pop_back();
3123 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3124 return MatchOperand_Success;
3127 MipsAsmParser::OperandMatchResultTy
3128 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3129 MCAsmParser &Parser = getParser();
3130 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3131 SmallVector<unsigned, 10> Regs;
3133 if (Parser.getTok().isNot(AsmToken::Dollar))
3134 return MatchOperand_ParseFail;
3136 SMLoc S = Parser.getTok().getLoc();
3138 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3139 return MatchOperand_ParseFail;
3141 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3142 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3143 Regs.push_back(RegNo);
3145 SMLoc E = Parser.getTok().getLoc();
3146 if (Parser.getTok().isNot(AsmToken::Comma)) {
3147 Error(E, "',' expected");
3148 return MatchOperand_ParseFail;
3154 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3155 return MatchOperand_ParseFail;
3157 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3158 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3159 Regs.push_back(RegNo);
3161 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3163 return MatchOperand_Success;
3166 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3168 MCSymbolRefExpr::VariantKind VK =
3169 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3170 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3171 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3172 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3173 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3174 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3175 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3176 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3177 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3178 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3179 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3180 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3181 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3182 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3183 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3184 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3185 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3186 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3187 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3188 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3189 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3190 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3191 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3192 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3193 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3194 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3195 .Default(MCSymbolRefExpr::VK_None);
3197 assert(VK != MCSymbolRefExpr::VK_None);
3202 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3204 /// ::= '(', register, ')'
3205 /// handle it before we iterate so we don't get tripped up by the lack of
3207 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3208 MCAsmParser &Parser = getParser();
3209 if (getLexer().is(AsmToken::LParen)) {
3211 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3213 if (parseOperand(Operands, Name)) {
3214 SMLoc Loc = getLexer().getLoc();
3215 Parser.eatToEndOfStatement();
3216 return Error(Loc, "unexpected token in argument list");
3218 if (Parser.getTok().isNot(AsmToken::RParen)) {
3219 SMLoc Loc = getLexer().getLoc();
3220 Parser.eatToEndOfStatement();
3221 return Error(Loc, "unexpected token, expected ')'");
3224 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3230 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3231 /// either one of these.
3232 /// ::= '[', register, ']'
3233 /// ::= '[', integer, ']'
3234 /// handle it before we iterate so we don't get tripped up by the lack of
3236 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3237 OperandVector &Operands) {
3238 MCAsmParser &Parser = getParser();
3239 if (getLexer().is(AsmToken::LBrac)) {
3241 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3243 if (parseOperand(Operands, Name)) {
3244 SMLoc Loc = getLexer().getLoc();
3245 Parser.eatToEndOfStatement();
3246 return Error(Loc, "unexpected token in argument list");
3248 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3249 SMLoc Loc = getLexer().getLoc();
3250 Parser.eatToEndOfStatement();
3251 return Error(Loc, "unexpected token, expected ']'");
3254 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3260 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3261 SMLoc NameLoc, OperandVector &Operands) {
3262 MCAsmParser &Parser = getParser();
3263 DEBUG(dbgs() << "ParseInstruction\n");
3265 // We have reached first instruction, module directive are now forbidden.
3266 getTargetStreamer().forbidModuleDirective();
3268 // Check if we have valid mnemonic
3269 if (!mnemonicIsValid(Name, 0)) {
3270 Parser.eatToEndOfStatement();
3271 return Error(NameLoc, "unknown instruction");
3273 // First operand in MCInst is instruction mnemonic.
3274 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3276 // Read the remaining operands.
3277 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3278 // Read the first operand.
3279 if (parseOperand(Operands, Name)) {
3280 SMLoc Loc = getLexer().getLoc();
3281 Parser.eatToEndOfStatement();
3282 return Error(Loc, "unexpected token in argument list");
3284 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3286 // AFAIK, parenthesis suffixes are never on the first operand
3288 while (getLexer().is(AsmToken::Comma)) {
3289 Parser.Lex(); // Eat the comma.
3290 // Parse and remember the operand.
3291 if (parseOperand(Operands, Name)) {
3292 SMLoc Loc = getLexer().getLoc();
3293 Parser.eatToEndOfStatement();
3294 return Error(Loc, "unexpected token in argument list");
3296 // Parse bracket and parenthesis suffixes before we iterate
3297 if (getLexer().is(AsmToken::LBrac)) {
3298 if (parseBracketSuffix(Name, Operands))
3300 } else if (getLexer().is(AsmToken::LParen) &&
3301 parseParenSuffix(Name, Operands))
3305 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3306 SMLoc Loc = getLexer().getLoc();
3307 Parser.eatToEndOfStatement();
3308 return Error(Loc, "unexpected token in argument list");
3310 Parser.Lex(); // Consume the EndOfStatement.
3314 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3315 MCAsmParser &Parser = getParser();
3316 SMLoc Loc = getLexer().getLoc();
3317 Parser.eatToEndOfStatement();
3318 return Error(Loc, ErrorMsg);
3321 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3322 return Error(Loc, ErrorMsg);
3325 bool MipsAsmParser::parseSetNoAtDirective() {
3326 MCAsmParser &Parser = getParser();
3327 // Line should look like: ".set noat".
3329 // Set the $at register to $0.
3330 AssemblerOptions.back()->setATRegIndex(0);
3332 Parser.Lex(); // Eat "noat".
3334 // If this is not the end of the statement, report an error.
3335 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3336 reportParseError("unexpected token, expected end of statement");
3340 getTargetStreamer().emitDirectiveSetNoAt();
3341 Parser.Lex(); // Consume the EndOfStatement.
3345 bool MipsAsmParser::parseSetAtDirective() {
3346 // Line can be: ".set at", which sets $at to $1
3347 // or ".set at=$reg", which sets $at to $reg.
3348 MCAsmParser &Parser = getParser();
3349 Parser.Lex(); // Eat "at".
3351 if (getLexer().is(AsmToken::EndOfStatement)) {
3352 // No register was specified, so we set $at to $1.
3353 AssemblerOptions.back()->setATRegIndex(1);
3355 getTargetStreamer().emitDirectiveSetAt();
3356 Parser.Lex(); // Consume the EndOfStatement.
3360 if (getLexer().isNot(AsmToken::Equal)) {
3361 reportParseError("unexpected token, expected equals sign");
3364 Parser.Lex(); // Eat "=".
3366 if (getLexer().isNot(AsmToken::Dollar)) {
3367 if (getLexer().is(AsmToken::EndOfStatement)) {
3368 reportParseError("no register specified");
3371 reportParseError("unexpected token, expected dollar sign '$'");
3375 Parser.Lex(); // Eat "$".
3377 // Find out what "reg" is.
3379 const AsmToken &Reg = Parser.getTok();
3380 if (Reg.is(AsmToken::Identifier)) {
3381 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3382 } else if (Reg.is(AsmToken::Integer)) {
3383 AtRegNo = Reg.getIntVal();
3385 reportParseError("unexpected token, expected identifier or integer");
3389 // Check if $reg is a valid register. If it is, set $at to $reg.
3390 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3391 reportParseError("invalid register");
3394 Parser.Lex(); // Eat "reg".
3396 // If this is not the end of the statement, report an error.
3397 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3398 reportParseError("unexpected token, expected end of statement");
3402 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3404 Parser.Lex(); // Consume the EndOfStatement.
3408 bool MipsAsmParser::parseSetReorderDirective() {
3409 MCAsmParser &Parser = getParser();
3411 // If this is not the end of the statement, report an error.
3412 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3413 reportParseError("unexpected token, expected end of statement");
3416 AssemblerOptions.back()->setReorder();
3417 getTargetStreamer().emitDirectiveSetReorder();
3418 Parser.Lex(); // Consume the EndOfStatement.
3422 bool MipsAsmParser::parseSetNoReorderDirective() {
3423 MCAsmParser &Parser = getParser();
3425 // If this is not the end of the statement, report an error.
3426 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3427 reportParseError("unexpected token, expected end of statement");
3430 AssemblerOptions.back()->setNoReorder();
3431 getTargetStreamer().emitDirectiveSetNoReorder();
3432 Parser.Lex(); // Consume the EndOfStatement.
3436 bool MipsAsmParser::parseSetMacroDirective() {
3437 MCAsmParser &Parser = getParser();
3439 // If this is not the end of the statement, report an error.
3440 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3441 reportParseError("unexpected token, expected end of statement");
3444 AssemblerOptions.back()->setMacro();
3445 Parser.Lex(); // Consume the EndOfStatement.
3449 bool MipsAsmParser::parseSetNoMacroDirective() {
3450 MCAsmParser &Parser = getParser();
3452 // If this is not the end of the statement, report an error.
3453 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3454 reportParseError("unexpected token, expected end of statement");
3457 if (AssemblerOptions.back()->isReorder()) {
3458 reportParseError("`noreorder' must be set before `nomacro'");
3461 AssemblerOptions.back()->setNoMacro();
3462 Parser.Lex(); // Consume the EndOfStatement.
3466 bool MipsAsmParser::parseSetMsaDirective() {
3467 MCAsmParser &Parser = getParser();
3470 // If this is not the end of the statement, report an error.
3471 if (getLexer().isNot(AsmToken::EndOfStatement))
3472 return reportParseError("unexpected token, expected end of statement");
3474 setFeatureBits(Mips::FeatureMSA, "msa");
3475 getTargetStreamer().emitDirectiveSetMsa();
3479 bool MipsAsmParser::parseSetNoMsaDirective() {
3480 MCAsmParser &Parser = getParser();
3483 // If this is not the end of the statement, report an error.
3484 if (getLexer().isNot(AsmToken::EndOfStatement))
3485 return reportParseError("unexpected token, expected end of statement");
3487 clearFeatureBits(Mips::FeatureMSA, "msa");
3488 getTargetStreamer().emitDirectiveSetNoMsa();
3492 bool MipsAsmParser::parseSetNoDspDirective() {
3493 MCAsmParser &Parser = getParser();
3494 Parser.Lex(); // Eat "nodsp".
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::FeatureDSP, "dsp");
3503 getTargetStreamer().emitDirectiveSetNoDsp();
3507 bool MipsAsmParser::parseSetMips16Directive() {
3508 MCAsmParser &Parser = getParser();
3509 Parser.Lex(); // Eat "mips16".
3511 // If this is not the end of the statement, report an error.
3512 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3513 reportParseError("unexpected token, expected end of statement");
3517 setFeatureBits(Mips::FeatureMips16, "mips16");
3518 getTargetStreamer().emitDirectiveSetMips16();
3519 Parser.Lex(); // Consume the EndOfStatement.
3523 bool MipsAsmParser::parseSetNoMips16Directive() {
3524 MCAsmParser &Parser = getParser();
3525 Parser.Lex(); // Eat "nomips16".
3527 // If this is not the end of the statement, report an error.
3528 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3529 reportParseError("unexpected token, expected end of statement");
3533 clearFeatureBits(Mips::FeatureMips16, "mips16");
3534 getTargetStreamer().emitDirectiveSetNoMips16();
3535 Parser.Lex(); // Consume the EndOfStatement.
3539 bool MipsAsmParser::parseSetFpDirective() {
3540 MCAsmParser &Parser = getParser();
3541 MipsABIFlagsSection::FpABIKind FpAbiVal;
3542 // Line can be: .set fp=32
3545 Parser.Lex(); // Eat fp token
3546 AsmToken Tok = Parser.getTok();
3547 if (Tok.isNot(AsmToken::Equal)) {
3548 reportParseError("unexpected token, expected equals sign '='");
3551 Parser.Lex(); // Eat '=' token.
3552 Tok = Parser.getTok();
3554 if (!parseFpABIValue(FpAbiVal, ".set"))
3557 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3558 reportParseError("unexpected token, expected end of statement");
3561 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3562 Parser.Lex(); // Consume the EndOfStatement.
3566 bool MipsAsmParser::parseSetPopDirective() {
3567 MCAsmParser &Parser = getParser();
3568 SMLoc Loc = getLexer().getLoc();
3571 if (getLexer().isNot(AsmToken::EndOfStatement))
3572 return reportParseError("unexpected token, expected end of statement");
3574 // Always keep an element on the options "stack" to prevent the user
3575 // from changing the initial options. This is how we remember them.
3576 if (AssemblerOptions.size() == 2)
3577 return reportParseError(Loc, ".set pop with no .set push");
3579 AssemblerOptions.pop_back();
3580 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3582 getTargetStreamer().emitDirectiveSetPop();
3586 bool MipsAsmParser::parseSetPushDirective() {
3587 MCAsmParser &Parser = getParser();
3589 if (getLexer().isNot(AsmToken::EndOfStatement))
3590 return reportParseError("unexpected token, expected end of statement");
3592 // Create a copy of the current assembler options environment and push it.
3593 AssemblerOptions.push_back(
3594 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3596 getTargetStreamer().emitDirectiveSetPush();
3600 bool MipsAsmParser::parseSetAssignment() {
3602 const MCExpr *Value;
3603 MCAsmParser &Parser = getParser();
3605 if (Parser.parseIdentifier(Name))
3606 reportParseError("expected identifier after .set");
3608 if (getLexer().isNot(AsmToken::Comma))
3609 return reportParseError("unexpected token, expected comma");
3612 if (Parser.parseExpression(Value))
3613 return reportParseError("expected valid expression after comma");
3615 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3616 Sym->setVariableValue(Value);
3621 bool MipsAsmParser::parseSetMips0Directive() {
3622 MCAsmParser &Parser = getParser();
3624 if (getLexer().isNot(AsmToken::EndOfStatement))
3625 return reportParseError("unexpected token, expected end of statement");
3627 // Reset assembler options to their initial values.
3628 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3629 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3631 getTargetStreamer().emitDirectiveSetMips0();
3635 bool MipsAsmParser::parseSetArchDirective() {
3636 MCAsmParser &Parser = getParser();
3638 if (getLexer().isNot(AsmToken::Equal))
3639 return reportParseError("unexpected token, expected equals sign");
3643 if (Parser.parseIdentifier(Arch))
3644 return reportParseError("expected arch identifier");
3646 StringRef ArchFeatureName =
3647 StringSwitch<StringRef>(Arch)
3648 .Case("mips1", "mips1")
3649 .Case("mips2", "mips2")
3650 .Case("mips3", "mips3")
3651 .Case("mips4", "mips4")
3652 .Case("mips5", "mips5")
3653 .Case("mips32", "mips32")
3654 .Case("mips32r2", "mips32r2")
3655 .Case("mips32r3", "mips32r3")
3656 .Case("mips32r5", "mips32r5")
3657 .Case("mips32r6", "mips32r6")
3658 .Case("mips64", "mips64")
3659 .Case("mips64r2", "mips64r2")
3660 .Case("mips64r3", "mips64r3")
3661 .Case("mips64r5", "mips64r5")
3662 .Case("mips64r6", "mips64r6")
3663 .Case("cnmips", "cnmips")
3664 .Case("r4000", "mips3") // This is an implementation of Mips3.
3667 if (ArchFeatureName.empty())
3668 return reportParseError("unsupported architecture");
3670 selectArch(ArchFeatureName);
3671 getTargetStreamer().emitDirectiveSetArch(Arch);
3675 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3676 MCAsmParser &Parser = getParser();
3678 if (getLexer().isNot(AsmToken::EndOfStatement))
3679 return reportParseError("unexpected token, expected end of statement");
3683 llvm_unreachable("Unimplemented feature");
3684 case Mips::FeatureDSP:
3685 setFeatureBits(Mips::FeatureDSP, "dsp");
3686 getTargetStreamer().emitDirectiveSetDsp();
3688 case Mips::FeatureMicroMips:
3689 getTargetStreamer().emitDirectiveSetMicroMips();
3691 case Mips::FeatureMips1:
3692 selectArch("mips1");
3693 getTargetStreamer().emitDirectiveSetMips1();
3695 case Mips::FeatureMips2:
3696 selectArch("mips2");
3697 getTargetStreamer().emitDirectiveSetMips2();
3699 case Mips::FeatureMips3:
3700 selectArch("mips3");
3701 getTargetStreamer().emitDirectiveSetMips3();
3703 case Mips::FeatureMips4:
3704 selectArch("mips4");
3705 getTargetStreamer().emitDirectiveSetMips4();
3707 case Mips::FeatureMips5:
3708 selectArch("mips5");
3709 getTargetStreamer().emitDirectiveSetMips5();
3711 case Mips::FeatureMips32:
3712 selectArch("mips32");
3713 getTargetStreamer().emitDirectiveSetMips32();
3715 case Mips::FeatureMips32r2:
3716 selectArch("mips32r2");
3717 getTargetStreamer().emitDirectiveSetMips32R2();
3719 case Mips::FeatureMips32r3:
3720 selectArch("mips32r3");
3721 getTargetStreamer().emitDirectiveSetMips32R3();
3723 case Mips::FeatureMips32r5:
3724 selectArch("mips32r5");
3725 getTargetStreamer().emitDirectiveSetMips32R5();
3727 case Mips::FeatureMips32r6:
3728 selectArch("mips32r6");
3729 getTargetStreamer().emitDirectiveSetMips32R6();
3731 case Mips::FeatureMips64:
3732 selectArch("mips64");
3733 getTargetStreamer().emitDirectiveSetMips64();
3735 case Mips::FeatureMips64r2:
3736 selectArch("mips64r2");
3737 getTargetStreamer().emitDirectiveSetMips64R2();
3739 case Mips::FeatureMips64r3:
3740 selectArch("mips64r3");
3741 getTargetStreamer().emitDirectiveSetMips64R3();
3743 case Mips::FeatureMips64r5:
3744 selectArch("mips64r5");
3745 getTargetStreamer().emitDirectiveSetMips64R5();
3747 case Mips::FeatureMips64r6:
3748 selectArch("mips64r6");
3749 getTargetStreamer().emitDirectiveSetMips64R6();
3755 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3756 MCAsmParser &Parser = getParser();
3757 if (getLexer().isNot(AsmToken::Comma)) {
3758 SMLoc Loc = getLexer().getLoc();
3759 Parser.eatToEndOfStatement();
3760 return Error(Loc, ErrorStr);
3763 Parser.Lex(); // Eat the comma.
3767 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3768 if (AssemblerOptions.back()->isReorder())
3769 Warning(Loc, ".cpload should be inside a noreorder section");
3771 if (inMips16Mode()) {
3772 reportParseError(".cpload is not supported in Mips16 mode");
3776 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3777 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3778 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3779 reportParseError("expected register containing function address");
3783 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3784 if (!RegOpnd.isGPRAsmReg()) {
3785 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3789 // If this is not the end of the statement, report an error.
3790 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3791 reportParseError("unexpected token, expected end of statement");
3795 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3799 bool MipsAsmParser::parseDirectiveCPSetup() {
3800 MCAsmParser &Parser = getParser();
3803 bool SaveIsReg = true;
3805 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3806 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3807 if (ResTy == MatchOperand_NoMatch) {
3808 reportParseError("expected register containing function address");
3809 Parser.eatToEndOfStatement();
3813 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3814 if (!FuncRegOpnd.isGPRAsmReg()) {
3815 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3816 Parser.eatToEndOfStatement();
3820 FuncReg = FuncRegOpnd.getGPR32Reg();
3823 if (!eatComma("unexpected token, expected comma"))
3826 ResTy = parseAnyRegister(TmpReg);
3827 if (ResTy == MatchOperand_NoMatch) {
3828 const AsmToken &Tok = Parser.getTok();
3829 if (Tok.is(AsmToken::Integer)) {
3830 Save = Tok.getIntVal();
3834 reportParseError("expected save register or stack offset");
3835 Parser.eatToEndOfStatement();
3839 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3840 if (!SaveOpnd.isGPRAsmReg()) {
3841 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3842 Parser.eatToEndOfStatement();
3845 Save = SaveOpnd.getGPR32Reg();
3848 if (!eatComma("unexpected token, expected comma"))
3852 if (Parser.parseExpression(Expr)) {
3853 reportParseError("expected expression");
3857 if (Expr->getKind() != MCExpr::SymbolRef) {
3858 reportParseError("expected symbol");
3861 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3863 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3868 bool MipsAsmParser::parseDirectiveNaN() {
3869 MCAsmParser &Parser = getParser();
3870 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3871 const AsmToken &Tok = Parser.getTok();
3873 if (Tok.getString() == "2008") {
3875 getTargetStreamer().emitDirectiveNaN2008();
3877 } else if (Tok.getString() == "legacy") {
3879 getTargetStreamer().emitDirectiveNaNLegacy();
3883 // If we don't recognize the option passed to the .nan
3884 // directive (e.g. no option or unknown option), emit an error.
3885 reportParseError("invalid option in .nan directive");
3889 bool MipsAsmParser::parseDirectiveSet() {
3890 MCAsmParser &Parser = getParser();
3891 // Get the next token.
3892 const AsmToken &Tok = Parser.getTok();
3894 if (Tok.getString() == "noat") {
3895 return parseSetNoAtDirective();
3896 } else if (Tok.getString() == "at") {
3897 return parseSetAtDirective();
3898 } else if (Tok.getString() == "arch") {
3899 return parseSetArchDirective();
3900 } else if (Tok.getString() == "fp") {
3901 return parseSetFpDirective();
3902 } else if (Tok.getString() == "pop") {
3903 return parseSetPopDirective();
3904 } else if (Tok.getString() == "push") {
3905 return parseSetPushDirective();
3906 } else if (Tok.getString() == "reorder") {
3907 return parseSetReorderDirective();
3908 } else if (Tok.getString() == "noreorder") {
3909 return parseSetNoReorderDirective();
3910 } else if (Tok.getString() == "macro") {
3911 return parseSetMacroDirective();
3912 } else if (Tok.getString() == "nomacro") {
3913 return parseSetNoMacroDirective();
3914 } else if (Tok.getString() == "mips16") {
3915 return parseSetMips16Directive();
3916 } else if (Tok.getString() == "nomips16") {
3917 return parseSetNoMips16Directive();
3918 } else if (Tok.getString() == "nomicromips") {
3919 getTargetStreamer().emitDirectiveSetNoMicroMips();
3920 Parser.eatToEndOfStatement();
3922 } else if (Tok.getString() == "micromips") {
3923 return parseSetFeature(Mips::FeatureMicroMips);
3924 } else if (Tok.getString() == "mips0") {
3925 return parseSetMips0Directive();
3926 } else if (Tok.getString() == "mips1") {
3927 return parseSetFeature(Mips::FeatureMips1);
3928 } else if (Tok.getString() == "mips2") {
3929 return parseSetFeature(Mips::FeatureMips2);
3930 } else if (Tok.getString() == "mips3") {
3931 return parseSetFeature(Mips::FeatureMips3);
3932 } else if (Tok.getString() == "mips4") {
3933 return parseSetFeature(Mips::FeatureMips4);
3934 } else if (Tok.getString() == "mips5") {
3935 return parseSetFeature(Mips::FeatureMips5);
3936 } else if (Tok.getString() == "mips32") {
3937 return parseSetFeature(Mips::FeatureMips32);
3938 } else if (Tok.getString() == "mips32r2") {
3939 return parseSetFeature(Mips::FeatureMips32r2);
3940 } else if (Tok.getString() == "mips32r3") {
3941 return parseSetFeature(Mips::FeatureMips32r3);
3942 } else if (Tok.getString() == "mips32r5") {
3943 return parseSetFeature(Mips::FeatureMips32r5);
3944 } else if (Tok.getString() == "mips32r6") {
3945 return parseSetFeature(Mips::FeatureMips32r6);
3946 } else if (Tok.getString() == "mips64") {
3947 return parseSetFeature(Mips::FeatureMips64);
3948 } else if (Tok.getString() == "mips64r2") {
3949 return parseSetFeature(Mips::FeatureMips64r2);
3950 } else if (Tok.getString() == "mips64r3") {
3951 return parseSetFeature(Mips::FeatureMips64r3);
3952 } else if (Tok.getString() == "mips64r5") {
3953 return parseSetFeature(Mips::FeatureMips64r5);
3954 } else if (Tok.getString() == "mips64r6") {
3955 return parseSetFeature(Mips::FeatureMips64r6);
3956 } else if (Tok.getString() == "dsp") {
3957 return parseSetFeature(Mips::FeatureDSP);
3958 } else if (Tok.getString() == "nodsp") {
3959 return parseSetNoDspDirective();
3960 } else if (Tok.getString() == "msa") {
3961 return parseSetMsaDirective();
3962 } else if (Tok.getString() == "nomsa") {
3963 return parseSetNoMsaDirective();
3965 // It is just an identifier, look for an assignment.
3966 parseSetAssignment();
3973 /// parseDataDirective
3974 /// ::= .word [ expression (, expression)* ]
3975 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3976 MCAsmParser &Parser = getParser();
3977 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3979 const MCExpr *Value;
3980 if (getParser().parseExpression(Value))
3983 getParser().getStreamer().EmitValue(Value, Size);
3985 if (getLexer().is(AsmToken::EndOfStatement))
3988 if (getLexer().isNot(AsmToken::Comma))
3989 return Error(L, "unexpected token, expected comma");
3998 /// parseDirectiveGpWord
3999 /// ::= .gpword local_sym
4000 bool MipsAsmParser::parseDirectiveGpWord() {
4001 MCAsmParser &Parser = getParser();
4002 const MCExpr *Value;
4003 // EmitGPRel32Value requires an expression, so we are using base class
4004 // method to evaluate the expression.
4005 if (getParser().parseExpression(Value))
4007 getParser().getStreamer().EmitGPRel32Value(Value);
4009 if (getLexer().isNot(AsmToken::EndOfStatement))
4010 return Error(getLexer().getLoc(),
4011 "unexpected token, expected end of statement");
4012 Parser.Lex(); // Eat EndOfStatement token.
4016 /// parseDirectiveGpDWord
4017 /// ::= .gpdword local_sym
4018 bool MipsAsmParser::parseDirectiveGpDWord() {
4019 MCAsmParser &Parser = getParser();
4020 const MCExpr *Value;
4021 // EmitGPRel64Value requires an expression, so we are using base class
4022 // method to evaluate the expression.
4023 if (getParser().parseExpression(Value))
4025 getParser().getStreamer().EmitGPRel64Value(Value);
4027 if (getLexer().isNot(AsmToken::EndOfStatement))
4028 return Error(getLexer().getLoc(),
4029 "unexpected token, expected end of statement");
4030 Parser.Lex(); // Eat EndOfStatement token.
4034 bool MipsAsmParser::parseDirectiveOption() {
4035 MCAsmParser &Parser = getParser();
4036 // Get the option token.
4037 AsmToken Tok = Parser.getTok();
4038 // At the moment only identifiers are supported.
4039 if (Tok.isNot(AsmToken::Identifier)) {
4040 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4041 Parser.eatToEndOfStatement();
4045 StringRef Option = Tok.getIdentifier();
4047 if (Option == "pic0") {
4048 getTargetStreamer().emitDirectiveOptionPic0();
4050 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4051 Error(Parser.getTok().getLoc(),
4052 "unexpected token, expected end of statement");
4053 Parser.eatToEndOfStatement();
4058 if (Option == "pic2") {
4059 getTargetStreamer().emitDirectiveOptionPic2();
4061 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4062 Error(Parser.getTok().getLoc(),
4063 "unexpected token, expected end of statement");
4064 Parser.eatToEndOfStatement();
4070 Warning(Parser.getTok().getLoc(),
4071 "unknown option, expected 'pic0' or 'pic2'");
4072 Parser.eatToEndOfStatement();
4076 /// parseInsnDirective
4078 bool MipsAsmParser::parseInsnDirective() {
4079 // If this is not the end of the statement, report an error.
4080 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4081 reportParseError("unexpected token, expected end of statement");
4085 // The actual label marking happens in
4086 // MipsELFStreamer::createPendingLabelRelocs().
4087 getTargetStreamer().emitDirectiveInsn();
4089 getParser().Lex(); // Eat EndOfStatement token.
4093 /// parseDirectiveModule
4094 /// ::= .module oddspreg
4095 /// ::= .module nooddspreg
4096 /// ::= .module fp=value
4097 bool MipsAsmParser::parseDirectiveModule() {
4098 MCAsmParser &Parser = getParser();
4099 MCAsmLexer &Lexer = getLexer();
4100 SMLoc L = Lexer.getLoc();
4102 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4103 // TODO : get a better message.
4104 reportParseError(".module directive must appear before any code");
4109 if (Parser.parseIdentifier(Option)) {
4110 reportParseError("expected .module option identifier");
4114 if (Option == "oddspreg") {
4115 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4116 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4118 // If this is not the end of the statement, report an error.
4119 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4120 reportParseError("unexpected token, expected end of statement");
4124 return false; // parseDirectiveModule has finished successfully.
4125 } else if (Option == "nooddspreg") {
4127 Error(L, "'.module nooddspreg' requires the O32 ABI");
4131 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4132 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4134 // If this is not the end of the statement, report an error.
4135 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4136 reportParseError("unexpected token, expected end of statement");
4140 return false; // parseDirectiveModule has finished successfully.
4141 } else if (Option == "fp") {
4142 return parseDirectiveModuleFP();
4144 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4148 /// parseDirectiveModuleFP
4152 bool MipsAsmParser::parseDirectiveModuleFP() {
4153 MCAsmParser &Parser = getParser();
4154 MCAsmLexer &Lexer = getLexer();
4156 if (Lexer.isNot(AsmToken::Equal)) {
4157 reportParseError("unexpected token, expected equals sign '='");
4160 Parser.Lex(); // Eat '=' token.
4162 MipsABIFlagsSection::FpABIKind FpABI;
4163 if (!parseFpABIValue(FpABI, ".module"))
4166 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4167 reportParseError("unexpected token, expected end of statement");
4171 // Emit appropriate flags.
4172 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4173 Parser.Lex(); // Consume the EndOfStatement.
4177 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4178 StringRef Directive) {
4179 MCAsmParser &Parser = getParser();
4180 MCAsmLexer &Lexer = getLexer();
4182 if (Lexer.is(AsmToken::Identifier)) {
4183 StringRef Value = Parser.getTok().getString();
4186 if (Value != "xx") {
4187 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4192 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4196 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4200 if (Lexer.is(AsmToken::Integer)) {
4201 unsigned Value = Parser.getTok().getIntVal();
4204 if (Value != 32 && Value != 64) {
4205 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4211 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4215 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4217 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4225 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4226 MCAsmParser &Parser = getParser();
4227 StringRef IDVal = DirectiveID.getString();
4229 if (IDVal == ".cpload")
4230 return parseDirectiveCpLoad(DirectiveID.getLoc());
4231 if (IDVal == ".dword") {
4232 parseDataDirective(8, DirectiveID.getLoc());
4235 if (IDVal == ".ent") {
4236 StringRef SymbolName;
4238 if (Parser.parseIdentifier(SymbolName)) {
4239 reportParseError("expected identifier after .ent");
4243 // There's an undocumented extension that allows an integer to
4244 // follow the name of the procedure which AFAICS is ignored by GAS.
4245 // Example: .ent foo,2
4246 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4247 if (getLexer().isNot(AsmToken::Comma)) {
4248 // Even though we accept this undocumented extension for compatibility
4249 // reasons, the additional integer argument does not actually change
4250 // the behaviour of the '.ent' directive, so we would like to discourage
4251 // its use. We do this by not referring to the extended version in
4252 // error messages which are not directly related to its use.
4253 reportParseError("unexpected token, expected end of statement");
4256 Parser.Lex(); // Eat the comma.
4257 const MCExpr *DummyNumber;
4258 int64_t DummyNumberVal;
4259 // If the user was explicitly trying to use the extended version,
4260 // we still give helpful extension-related error messages.
4261 if (Parser.parseExpression(DummyNumber)) {
4262 reportParseError("expected number after comma");
4265 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4266 reportParseError("expected an absolute expression after comma");
4271 // If this is not the end of the statement, report an error.
4272 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4273 reportParseError("unexpected token, expected end of statement");
4277 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4279 getTargetStreamer().emitDirectiveEnt(*Sym);
4284 if (IDVal == ".end") {
4285 StringRef SymbolName;
4287 if (Parser.parseIdentifier(SymbolName)) {
4288 reportParseError("expected identifier after .end");
4292 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4293 reportParseError("unexpected token, expected end of statement");
4297 if (CurrentFn == nullptr) {
4298 reportParseError(".end used without .ent");
4302 if ((SymbolName != CurrentFn->getName())) {
4303 reportParseError(".end symbol does not match .ent symbol");
4307 getTargetStreamer().emitDirectiveEnd(SymbolName);
4308 CurrentFn = nullptr;
4312 if (IDVal == ".frame") {
4313 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4314 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4315 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4316 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4317 reportParseError("expected stack register");
4321 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4322 if (!StackRegOpnd.isGPRAsmReg()) {
4323 reportParseError(StackRegOpnd.getStartLoc(),
4324 "expected general purpose register");
4327 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4329 if (Parser.getTok().is(AsmToken::Comma))
4332 reportParseError("unexpected token, expected comma");
4336 // Parse the frame size.
4337 const MCExpr *FrameSize;
4338 int64_t FrameSizeVal;
4340 if (Parser.parseExpression(FrameSize)) {
4341 reportParseError("expected frame size value");
4345 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4346 reportParseError("frame size not an absolute expression");
4350 if (Parser.getTok().is(AsmToken::Comma))
4353 reportParseError("unexpected token, expected comma");
4357 // Parse the return register.
4359 ResTy = parseAnyRegister(TmpReg);
4360 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4361 reportParseError("expected return register");
4365 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4366 if (!ReturnRegOpnd.isGPRAsmReg()) {
4367 reportParseError(ReturnRegOpnd.getStartLoc(),
4368 "expected general purpose register");
4372 // If this is not the end of the statement, report an error.
4373 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4374 reportParseError("unexpected token, expected end of statement");
4378 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4379 ReturnRegOpnd.getGPR32Reg());
4383 if (IDVal == ".set") {
4384 return parseDirectiveSet();
4387 if (IDVal == ".mask" || IDVal == ".fmask") {
4388 // .mask bitmask, frame_offset
4389 // bitmask: One bit for each register used.
4390 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4391 // first register is expected to be saved.
4393 // .mask 0x80000000, -4
4394 // .fmask 0x80000000, -4
4397 // Parse the bitmask
4398 const MCExpr *BitMask;
4401 if (Parser.parseExpression(BitMask)) {
4402 reportParseError("expected bitmask value");
4406 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4407 reportParseError("bitmask not an absolute expression");
4411 if (Parser.getTok().is(AsmToken::Comma))
4414 reportParseError("unexpected token, expected comma");
4418 // Parse the frame_offset
4419 const MCExpr *FrameOffset;
4420 int64_t FrameOffsetVal;
4422 if (Parser.parseExpression(FrameOffset)) {
4423 reportParseError("expected frame offset value");
4427 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4428 reportParseError("frame offset not an absolute expression");
4432 // If this is not the end of the statement, report an error.
4433 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4434 reportParseError("unexpected token, expected end of statement");
4438 if (IDVal == ".mask")
4439 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4441 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4445 if (IDVal == ".nan")
4446 return parseDirectiveNaN();
4448 if (IDVal == ".gpword") {
4449 parseDirectiveGpWord();
4453 if (IDVal == ".gpdword") {
4454 parseDirectiveGpDWord();
4458 if (IDVal == ".word") {
4459 parseDataDirective(4, DirectiveID.getLoc());
4463 if (IDVal == ".option")
4464 return parseDirectiveOption();
4466 if (IDVal == ".abicalls") {
4467 getTargetStreamer().emitDirectiveAbiCalls();
4468 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4469 Error(Parser.getTok().getLoc(),
4470 "unexpected token, expected end of statement");
4472 Parser.eatToEndOfStatement();
4477 if (IDVal == ".cpsetup")
4478 return parseDirectiveCPSetup();
4480 if (IDVal == ".module")
4481 return parseDirectiveModule();
4483 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4484 return parseInternalDirectiveReallowModule();
4486 if (IDVal == ".insn")
4487 return parseInsnDirective();
4492 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4493 // If this is not the end of the statement, report an error.
4494 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4495 reportParseError("unexpected token, expected end of statement");
4499 getTargetStreamer().reallowModuleDirective();
4501 getParser().Lex(); // Eat EndOfStatement token.
4505 extern "C" void LLVMInitializeMipsAsmParser() {
4506 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4507 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4508 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4509 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4512 #define GET_REGISTER_MATCHER
4513 #define GET_MATCHER_IMPLEMENTATION
4514 #include "MipsGenAsmMatcher.inc"