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(const FeatureBitset &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 const FeatureBitset &getFeatures() const { return Features; }
74 void setFeatures(const FeatureBitset &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 FeatureBitset AllArchRelatedMask;
87 FeatureBitset Features;
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103 class MipsAsmParser : public MCTargetAsmParser {
104 MipsTargetStreamer &getTargetStreamer() {
105 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
106 return static_cast<MipsTargetStreamer &>(TS);
109 MCSubtargetInfo &STI;
111 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
112 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113 // nullptr, which indicates that no function is currently
114 // selected. This usually happens after an '.end func'
117 // Print a warning along with its fix-it message at the given range.
118 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
119 SMRange Range, bool ShowColors = true);
121 #define GET_ASSEMBLER_HEADER
122 #include "MipsGenAsmMatcher.inc"
124 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
126 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
127 OperandVector &Operands, MCStreamer &Out,
129 bool MatchingInlineAsm) override;
131 /// Parse a register as used in CFI directives
132 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
134 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
136 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
138 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
139 SMLoc NameLoc, OperandVector &Operands) override;
141 bool ParseDirective(AsmToken DirectiveID) override;
143 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy
146 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
147 StringRef Identifier, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy
150 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
152 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
154 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
156 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
158 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
160 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseRegisterPair (OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseMovePRegPair(OperandVector &Operands);
168 MipsAsmParser::OperandMatchResultTy
169 parseRegisterList (OperandVector &Operands);
171 bool searchSymbolAlias(OperandVector &Operands);
173 bool parseOperand(OperandVector &, StringRef Mnemonic);
175 bool needsExpansion(MCInst &Inst);
177 // Expands assembly pseudo instructions.
178 // Returns false on success, true otherwise.
179 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
186 bool Is32BitImm, SMLoc IDLoc,
187 SmallVectorImpl<MCInst> &Instructions);
189 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
195 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions);
197 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 void expandLoadAddressSym(const MCOperand &DstRegOp, const MCOperand &SymOp,
201 bool Is32BitSym, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions);
204 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
205 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
208 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
215 SmallVectorImpl<MCInst> &Instructions);
217 bool reportParseError(Twine ErrorMsg);
218 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
220 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
221 bool parseRelocOperand(const MCExpr *&Res);
223 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
225 bool isEvaluated(const MCExpr *Expr);
226 bool parseSetMips0Directive();
227 bool parseSetArchDirective();
228 bool parseSetFeature(uint64_t Feature);
229 bool parseDirectiveCpLoad(SMLoc Loc);
230 bool parseDirectiveCPSetup();
231 bool parseDirectiveNaN();
232 bool parseDirectiveSet();
233 bool parseDirectiveOption();
234 bool parseInsnDirective();
236 bool parseSetAtDirective();
237 bool parseSetNoAtDirective();
238 bool parseSetMacroDirective();
239 bool parseSetNoMacroDirective();
240 bool parseSetMsaDirective();
241 bool parseSetNoMsaDirective();
242 bool parseSetNoDspDirective();
243 bool parseSetReorderDirective();
244 bool parseSetNoReorderDirective();
245 bool parseSetMips16Directive();
246 bool parseSetNoMips16Directive();
247 bool parseSetFpDirective();
248 bool parseSetPopDirective();
249 bool parseSetPushDirective();
250 bool parseSetSoftFloatDirective();
251 bool parseSetHardFloatDirective();
253 bool parseSetAssignment();
255 bool parseDataDirective(unsigned Size, SMLoc L);
256 bool parseDirectiveGpWord();
257 bool parseDirectiveGpDWord();
258 bool parseDirectiveModule();
259 bool parseDirectiveModuleFP();
260 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
261 StringRef Directive);
263 bool parseInternalDirectiveReallowModule();
265 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
267 bool eatComma(StringRef ErrorStr);
269 int matchCPURegisterName(StringRef Symbol);
271 int matchHWRegsRegisterName(StringRef Symbol);
273 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
275 int matchFPURegisterName(StringRef Name);
277 int matchFCCRegisterName(StringRef Name);
279 int matchACRegisterName(StringRef Name);
281 int matchMSA128RegisterName(StringRef Name);
283 int matchMSA128CtrlRegisterName(StringRef Name);
285 unsigned getReg(int RC, int RegNo);
287 unsigned getGPR(int RegNo);
289 /// Returns the internal register number for the current AT. Also checks if
290 /// the current AT is unavailable (set to $0) and gives an error if it is.
291 /// This should be used in pseudo-instruction expansions which need AT.
292 unsigned getATReg(SMLoc Loc);
294 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
295 SmallVectorImpl<MCInst> &Instructions);
297 // Helper function that checks if the value of a vector index is within the
298 // boundaries of accepted values for each RegisterKind
299 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
300 bool validateMSAIndex(int Val, int RegKind);
302 // Selects a new architecture by updating the FeatureBits with the necessary
303 // info including implied dependencies.
304 // Internally, it clears all the feature bits related to *any* architecture
305 // and selects the new one using the ToggleFeature functionality of the
306 // MCSubtargetInfo object that handles implied dependencies. The reason we
307 // clear all the arch related bits manually is because ToggleFeature only
308 // clears the features that imply the feature being cleared and not the
309 // features implied by the feature being cleared. This is easier to see
311 // --------------------------------------------------
312 // | Feature | Implies |
313 // | -------------------------------------------------|
314 // | FeatureMips1 | None |
315 // | FeatureMips2 | FeatureMips1 |
316 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
317 // | FeatureMips4 | FeatureMips3 |
319 // --------------------------------------------------
321 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
322 // FeatureMipsGP64 | FeatureMips1)
323 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
324 void selectArch(StringRef ArchFeature) {
325 FeatureBitset FeatureBits = STI.getFeatureBits();
326 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
327 STI.setFeatureBits(FeatureBits);
328 setAvailableFeatures(
329 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
330 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
333 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
334 if (!(STI.getFeatureBits()[Feature])) {
335 setAvailableFeatures(
336 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
337 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
341 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
342 if (STI.getFeatureBits()[Feature]) {
343 setAvailableFeatures(
344 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
345 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
350 enum MipsMatchResultTy {
351 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
352 #define GET_OPERAND_DIAGNOSTIC_TYPES
353 #include "MipsGenAsmMatcher.inc"
354 #undef GET_OPERAND_DIAGNOSTIC_TYPES
358 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
359 const MCInstrInfo &MII, const MCTargetOptions &Options)
360 : MCTargetAsmParser(), STI(sti),
361 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
362 sti.getCPU(), Options)) {
363 MCAsmParserExtension::Initialize(parser);
365 parser.addAliasForDirective(".asciiz", ".asciz");
367 // Initialize the set of available features.
368 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
370 // Remember the initial assembler options. The user can not modify these.
371 AssemblerOptions.push_back(
372 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
374 // Create an assembler options environment for the user to modify.
375 AssemblerOptions.push_back(
376 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
378 getTargetStreamer().updateABIInfo(*this);
380 if (!isABI_O32() && !useOddSPReg() != 0)
381 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
386 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
387 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
389 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
390 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
391 const MipsABIInfo &getABI() const { return ABI; }
392 bool isABI_N32() const { return ABI.IsN32(); }
393 bool isABI_N64() const { return ABI.IsN64(); }
394 bool isABI_O32() const { return ABI.IsO32(); }
395 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
397 bool useOddSPReg() const {
398 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
401 bool inMicroMipsMode() const {
402 return STI.getFeatureBits()[Mips::FeatureMicroMips];
404 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
405 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
406 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
407 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
408 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
409 bool hasMips32() const {
410 return STI.getFeatureBits()[Mips::FeatureMips32];
412 bool hasMips64() const {
413 return STI.getFeatureBits()[Mips::FeatureMips64];
415 bool hasMips32r2() const {
416 return STI.getFeatureBits()[Mips::FeatureMips32r2];
418 bool hasMips64r2() const {
419 return STI.getFeatureBits()[Mips::FeatureMips64r2];
421 bool hasMips32r3() const {
422 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
424 bool hasMips64r3() const {
425 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
427 bool hasMips32r5() const {
428 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
430 bool hasMips64r5() const {
431 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
433 bool hasMips32r6() const {
434 return STI.getFeatureBits()[Mips::FeatureMips32r6];
436 bool hasMips64r6() const {
437 return STI.getFeatureBits()[Mips::FeatureMips64r6];
440 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
441 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
442 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
443 bool hasCnMips() const {
444 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
447 bool inMips16Mode() const {
448 return STI.getFeatureBits()[Mips::FeatureMips16];
451 bool useSoftFloat() const {
452 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
455 /// Warn if RegIndex is the same as the current AT.
456 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
458 void warnIfNoMacro(SMLoc Loc);
464 /// MipsOperand - Instances of this class represent a parsed Mips machine
466 class MipsOperand : public MCParsedAsmOperand {
468 /// Broad categories of register classes
469 /// The exact class is finalized by the render method.
471 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
472 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
474 RegKind_FCC = 4, /// FCC
475 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
476 RegKind_MSACtrl = 16, /// MSA control registers
477 RegKind_COP2 = 32, /// COP2
478 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
480 RegKind_CCR = 128, /// CCR
481 RegKind_HWRegs = 256, /// HWRegs
482 RegKind_COP3 = 512, /// COP3
484 /// Potentially any (e.g. $1)
485 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
486 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
487 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
492 k_Immediate, /// An immediate (possibly involving symbol references)
493 k_Memory, /// Base + Offset Memory Address
494 k_PhysRegister, /// A physical register from the Mips namespace
495 k_RegisterIndex, /// A register index in one or more RegKind.
496 k_Token, /// A simple token
497 k_RegList, /// A physical register list
498 k_RegPair /// A pair of physical register
502 MipsOperand(KindTy K, MipsAsmParser &Parser)
503 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
506 /// For diagnostics, and checking the assembler temporary
507 MipsAsmParser &AsmParser;
515 unsigned Num; /// Register Number
519 unsigned Index; /// Index into the register class
520 RegKind Kind; /// Bitfield of the kinds it could possibly be
521 const MCRegisterInfo *RegInfo;
534 SmallVector<unsigned, 10> *List;
539 struct PhysRegOp PhysReg;
540 struct RegIdxOp RegIdx;
543 struct RegListOp RegList;
546 SMLoc StartLoc, EndLoc;
548 /// Internal constructor for register kinds
549 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
550 const MCRegisterInfo *RegInfo,
552 MipsAsmParser &Parser) {
553 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
554 Op->RegIdx.Index = Index;
555 Op->RegIdx.RegInfo = RegInfo;
556 Op->RegIdx.Kind = RegKind;
563 /// Coerce the register to GPR32 and return the real register for the current
565 unsigned getGPR32Reg() const {
566 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
567 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
568 unsigned ClassID = Mips::GPR32RegClassID;
569 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
572 /// Coerce the register to GPR32 and return the real register for the current
574 unsigned getGPRMM16Reg() const {
575 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
576 unsigned ClassID = Mips::GPR32RegClassID;
577 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
580 /// Coerce the register to GPR64 and return the real register for the current
582 unsigned getGPR64Reg() const {
583 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
584 unsigned ClassID = Mips::GPR64RegClassID;
585 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
589 /// Coerce the register to AFGR64 and return the real register for the current
591 unsigned getAFGR64Reg() const {
592 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
593 if (RegIdx.Index % 2 != 0)
594 AsmParser.Warning(StartLoc, "Float register should be even.");
595 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
596 .getRegister(RegIdx.Index / 2);
599 /// Coerce the register to FGR64 and return the real register for the current
601 unsigned getFGR64Reg() const {
602 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
603 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
604 .getRegister(RegIdx.Index);
607 /// Coerce the register to FGR32 and return the real register for the current
609 unsigned getFGR32Reg() const {
610 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
611 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
612 .getRegister(RegIdx.Index);
615 /// Coerce the register to FGRH32 and return the real register for the current
617 unsigned getFGRH32Reg() const {
618 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
619 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
620 .getRegister(RegIdx.Index);
623 /// Coerce the register to FCC and return the real register for the current
625 unsigned getFCCReg() const {
626 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
627 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
628 .getRegister(RegIdx.Index);
631 /// Coerce the register to MSA128 and return the real register for the current
633 unsigned getMSA128Reg() const {
634 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
635 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
637 unsigned ClassID = Mips::MSA128BRegClassID;
638 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
641 /// Coerce the register to MSACtrl and return the real register for the
643 unsigned getMSACtrlReg() const {
644 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
645 unsigned ClassID = Mips::MSACtrlRegClassID;
646 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
649 /// Coerce the register to COP2 and return the real register for the
651 unsigned getCOP2Reg() const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
653 unsigned ClassID = Mips::COP2RegClassID;
654 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
657 /// Coerce the register to COP3 and return the real register for the
659 unsigned getCOP3Reg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
661 unsigned ClassID = Mips::COP3RegClassID;
662 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
665 /// Coerce the register to ACC64DSP and return the real register for the
667 unsigned getACC64DSPReg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
669 unsigned ClassID = Mips::ACC64DSPRegClassID;
670 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
673 /// Coerce the register to HI32DSP and return the real register for the
675 unsigned getHI32DSPReg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
677 unsigned ClassID = Mips::HI32DSPRegClassID;
678 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
681 /// Coerce the register to LO32DSP and return the real register for the
683 unsigned getLO32DSPReg() const {
684 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
685 unsigned ClassID = Mips::LO32DSPRegClassID;
686 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
689 /// Coerce the register to CCR and return the real register for the
691 unsigned getCCRReg() const {
692 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
693 unsigned ClassID = Mips::CCRRegClassID;
694 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
697 /// Coerce the register to HWRegs and return the real register for the
699 unsigned getHWRegsReg() const {
700 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
701 unsigned ClassID = Mips::HWRegsRegClassID;
702 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
706 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
707 // Add as immediate when possible. Null MCExpr = 0.
709 Inst.addOperand(MCOperand::createImm(0));
710 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
711 Inst.addOperand(MCOperand::createImm(CE->getValue()));
713 Inst.addOperand(MCOperand::createExpr(Expr));
716 void addRegOperands(MCInst &Inst, unsigned N) const {
717 llvm_unreachable("Use a custom parser instead");
720 /// Render the operand to an MCInst as a GPR32
721 /// Asserts if the wrong number of operands are requested, or the operand
722 /// is not a k_RegisterIndex compatible with RegKind_GPR
723 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
724 assert(N == 1 && "Invalid number of operands!");
725 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
728 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
729 assert(N == 1 && "Invalid number of operands!");
730 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
733 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
734 assert(N == 1 && "Invalid number of operands!");
735 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
738 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
739 assert(N == 1 && "Invalid number of operands!");
740 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
743 /// Render the operand to an MCInst as a GPR64
744 /// Asserts if the wrong number of operands are requested, or the operand
745 /// is not a k_RegisterIndex compatible with RegKind_GPR
746 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
747 assert(N == 1 && "Invalid number of operands!");
748 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
751 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
752 assert(N == 1 && "Invalid number of operands!");
753 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
756 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
757 assert(N == 1 && "Invalid number of operands!");
758 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
761 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
762 assert(N == 1 && "Invalid number of operands!");
763 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
764 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
765 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
766 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
770 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
771 assert(N == 1 && "Invalid number of operands!");
772 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
775 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
776 assert(N == 1 && "Invalid number of operands!");
777 Inst.addOperand(MCOperand::createReg(getFCCReg()));
780 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
781 assert(N == 1 && "Invalid number of operands!");
782 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
785 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
786 assert(N == 1 && "Invalid number of operands!");
787 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
790 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
791 assert(N == 1 && "Invalid number of operands!");
792 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
795 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
796 assert(N == 1 && "Invalid number of operands!");
797 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
800 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
801 assert(N == 1 && "Invalid number of operands!");
802 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
805 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
806 assert(N == 1 && "Invalid number of operands!");
807 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
810 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
811 assert(N == 1 && "Invalid number of operands!");
812 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
815 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
816 assert(N == 1 && "Invalid number of operands!");
817 Inst.addOperand(MCOperand::createReg(getCCRReg()));
820 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
821 assert(N == 1 && "Invalid number of operands!");
822 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
825 void addImmOperands(MCInst &Inst, unsigned N) const {
826 assert(N == 1 && "Invalid number of operands!");
827 const MCExpr *Expr = getImm();
831 void addMemOperands(MCInst &Inst, unsigned N) const {
832 assert(N == 2 && "Invalid number of operands!");
834 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
836 const MCExpr *Expr = getMemOff();
840 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 2 && "Invalid number of operands!");
843 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
845 const MCExpr *Expr = getMemOff();
849 void addRegListOperands(MCInst &Inst, unsigned N) const {
850 assert(N == 1 && "Invalid number of operands!");
852 for (auto RegNo : getRegList())
853 Inst.addOperand(MCOperand::createReg(RegNo));
856 void addRegPairOperands(MCInst &Inst, unsigned N) const {
857 assert(N == 2 && "Invalid number of operands!");
858 unsigned RegNo = getRegPair();
859 Inst.addOperand(MCOperand::createReg(RegNo++));
860 Inst.addOperand(MCOperand::createReg(RegNo));
863 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
864 assert(N == 2 && "Invalid number of operands!");
865 for (auto RegNo : getRegList())
866 Inst.addOperand(MCOperand::createReg(RegNo));
869 bool isReg() const override {
870 // As a special case until we sort out the definition of div/divu, pretend
871 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
872 if (isGPRAsmReg() && RegIdx.Index == 0)
875 return Kind == k_PhysRegister;
877 bool isRegIdx() const { return Kind == k_RegisterIndex; }
878 bool isImm() const override { return Kind == k_Immediate; }
879 bool isConstantImm() const {
880 return isImm() && dyn_cast<MCConstantExpr>(getImm());
882 template <unsigned Bits> bool isUImm() const {
883 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
885 bool isToken() const override {
886 // Note: It's not possible to pretend that other operand kinds are tokens.
887 // The matcher emitter checks tokens first.
888 return Kind == k_Token;
890 bool isMem() const override { return Kind == k_Memory; }
891 bool isConstantMemOff() const {
892 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
894 template <unsigned Bits> bool isMemWithSimmOffset() const {
895 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
897 bool isMemWithGRPMM16Base() const {
898 return isMem() && getMemBase()->isMM16AsmReg();
900 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
901 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
902 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
904 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
905 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
906 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
907 && (getMemBase()->getGPR32Reg() == Mips::SP);
909 bool isRegList16() const {
913 int Size = RegList.List->size();
914 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
915 RegList.List->back() != Mips::RA)
918 int PrevReg = *RegList.List->begin();
919 for (int i = 1; i < Size - 1; i++) {
920 int Reg = (*(RegList.List))[i];
921 if ( Reg != PrevReg + 1)
928 bool isInvNum() const { return Kind == k_Immediate; }
929 bool isLSAImm() const {
930 if (!isConstantImm())
932 int64_t Val = getConstantImm();
933 return 1 <= Val && Val <= 4;
935 bool isRegList() const { return Kind == k_RegList; }
936 bool isMovePRegPair() const {
937 if (Kind != k_RegList || RegList.List->size() != 2)
940 unsigned R0 = RegList.List->front();
941 unsigned R1 = RegList.List->back();
943 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
944 (R0 == Mips::A1 && R1 == Mips::A3) ||
945 (R0 == Mips::A2 && R1 == Mips::A3) ||
946 (R0 == Mips::A0 && R1 == Mips::S5) ||
947 (R0 == Mips::A0 && R1 == Mips::S6) ||
948 (R0 == Mips::A0 && R1 == Mips::A1) ||
949 (R0 == Mips::A0 && R1 == Mips::A2) ||
950 (R0 == Mips::A0 && R1 == Mips::A3))
956 StringRef getToken() const {
957 assert(Kind == k_Token && "Invalid access!");
958 return StringRef(Tok.Data, Tok.Length);
960 bool isRegPair() const { return Kind == k_RegPair; }
962 unsigned getReg() const override {
963 // As a special case until we sort out the definition of div/divu, pretend
964 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
965 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
966 RegIdx.Kind & RegKind_GPR)
967 return getGPR32Reg(); // FIXME: GPR64 too
969 assert(Kind == k_PhysRegister && "Invalid access!");
973 const MCExpr *getImm() const {
974 assert((Kind == k_Immediate) && "Invalid access!");
978 int64_t getConstantImm() const {
979 const MCExpr *Val = getImm();
980 return static_cast<const MCConstantExpr *>(Val)->getValue();
983 MipsOperand *getMemBase() const {
984 assert((Kind == k_Memory) && "Invalid access!");
988 const MCExpr *getMemOff() const {
989 assert((Kind == k_Memory) && "Invalid access!");
993 int64_t getConstantMemOff() const {
994 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
997 const SmallVectorImpl<unsigned> &getRegList() const {
998 assert((Kind == k_RegList) && "Invalid access!");
999 return *(RegList.List);
1002 unsigned getRegPair() const {
1003 assert((Kind == k_RegPair) && "Invalid access!");
1004 return RegIdx.Index;
1007 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1008 MipsAsmParser &Parser) {
1009 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1010 Op->Tok.Data = Str.data();
1011 Op->Tok.Length = Str.size();
1017 /// Create a numeric register (e.g. $1). The exact register remains
1018 /// unresolved until an instruction successfully matches
1019 static std::unique_ptr<MipsOperand>
1020 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1021 SMLoc E, MipsAsmParser &Parser) {
1022 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1023 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1026 /// Create a register that is definitely a GPR.
1027 /// This is typically only used for named registers such as $gp.
1028 static std::unique_ptr<MipsOperand>
1029 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1030 MipsAsmParser &Parser) {
1031 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1034 /// Create a register that is definitely a FGR.
1035 /// This is typically only used for named registers such as $f0.
1036 static std::unique_ptr<MipsOperand>
1037 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1038 MipsAsmParser &Parser) {
1039 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1042 /// Create a register that is definitely a HWReg.
1043 /// This is typically only used for named registers such as $hwr_cpunum.
1044 static std::unique_ptr<MipsOperand>
1045 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1046 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1047 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1050 /// Create a register that is definitely an FCC.
1051 /// This is typically only used for named registers such as $fcc0.
1052 static std::unique_ptr<MipsOperand>
1053 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1054 MipsAsmParser &Parser) {
1055 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1058 /// Create a register that is definitely an ACC.
1059 /// This is typically only used for named registers such as $ac0.
1060 static std::unique_ptr<MipsOperand>
1061 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1062 MipsAsmParser &Parser) {
1063 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1066 /// Create a register that is definitely an MSA128.
1067 /// This is typically only used for named registers such as $w0.
1068 static std::unique_ptr<MipsOperand>
1069 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1070 SMLoc E, MipsAsmParser &Parser) {
1071 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1074 /// Create a register that is definitely an MSACtrl.
1075 /// This is typically only used for named registers such as $msaaccess.
1076 static std::unique_ptr<MipsOperand>
1077 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1078 SMLoc E, MipsAsmParser &Parser) {
1079 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1082 static std::unique_ptr<MipsOperand>
1083 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1084 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1091 static std::unique_ptr<MipsOperand>
1092 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1093 SMLoc E, MipsAsmParser &Parser) {
1094 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1095 Op->Mem.Base = Base.release();
1102 static std::unique_ptr<MipsOperand>
1103 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1104 MipsAsmParser &Parser) {
1105 assert (Regs.size() > 0 && "Empty list not allowed");
1107 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1108 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1109 Op->StartLoc = StartLoc;
1110 Op->EndLoc = EndLoc;
1114 static std::unique_ptr<MipsOperand>
1115 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1116 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1117 Op->RegIdx.Index = RegNo;
1123 bool isGPRAsmReg() const {
1124 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1126 bool isMM16AsmReg() const {
1127 if (!(isRegIdx() && RegIdx.Kind))
1129 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1130 || RegIdx.Index == 16 || RegIdx.Index == 17);
1132 bool isMM16AsmRegZero() const {
1133 if (!(isRegIdx() && RegIdx.Kind))
1135 return (RegIdx.Index == 0 ||
1136 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1137 RegIdx.Index == 17);
1139 bool isMM16AsmRegMoveP() const {
1140 if (!(isRegIdx() && RegIdx.Kind))
1142 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1143 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1145 bool isFGRAsmReg() const {
1146 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1147 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1149 bool isHWRegsAsmReg() const {
1150 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1152 bool isCCRAsmReg() const {
1153 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1155 bool isFCCAsmReg() const {
1156 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1158 if (!AsmParser.hasEightFccRegisters())
1159 return RegIdx.Index == 0;
1160 return RegIdx.Index <= 7;
1162 bool isACCAsmReg() const {
1163 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1165 bool isCOP2AsmReg() const {
1166 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1168 bool isCOP3AsmReg() const {
1169 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1171 bool isMSA128AsmReg() const {
1172 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1174 bool isMSACtrlAsmReg() const {
1175 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1178 /// getStartLoc - Get the location of the first token of this operand.
1179 SMLoc getStartLoc() const override { return StartLoc; }
1180 /// getEndLoc - Get the location of the last token of this operand.
1181 SMLoc getEndLoc() const override { return EndLoc; }
1183 virtual ~MipsOperand() {
1191 delete RegList.List;
1192 case k_PhysRegister:
1193 case k_RegisterIndex:
1200 void print(raw_ostream &OS) const override {
1209 Mem.Base->print(OS);
1214 case k_PhysRegister:
1215 OS << "PhysReg<" << PhysReg.Num << ">";
1217 case k_RegisterIndex:
1218 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1225 for (auto Reg : (*RegList.List))
1230 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1234 }; // class MipsOperand
1238 extern const MCInstrDesc MipsInsts[];
1240 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1241 return MipsInsts[Opcode];
1244 static bool hasShortDelaySlot(unsigned Opcode) {
1247 case Mips::JALRS_MM:
1248 case Mips::JALRS16_MM:
1249 case Mips::BGEZALS_MM:
1250 case Mips::BLTZALS_MM:
1257 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1258 SmallVectorImpl<MCInst> &Instructions) {
1259 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1263 if (MCID.isBranch() || MCID.isCall()) {
1264 const unsigned Opcode = Inst.getOpcode();
1274 assert(hasCnMips() && "instruction only valid for octeon cpus");
1281 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1282 Offset = Inst.getOperand(2);
1283 if (!Offset.isImm())
1284 break; // We'll deal with this situation later on when applying fixups.
1285 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1286 return Error(IDLoc, "branch target out of range");
1287 if (OffsetToAlignment(Offset.getImm(),
1288 1LL << (inMicroMipsMode() ? 1 : 2)))
1289 return Error(IDLoc, "branch to misaligned address");
1303 case Mips::BGEZAL_MM:
1304 case Mips::BLTZAL_MM:
1307 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1308 Offset = Inst.getOperand(1);
1309 if (!Offset.isImm())
1310 break; // We'll deal with this situation later on when applying fixups.
1311 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1312 return Error(IDLoc, "branch target out of range");
1313 if (OffsetToAlignment(Offset.getImm(),
1314 1LL << (inMicroMipsMode() ? 1 : 2)))
1315 return Error(IDLoc, "branch to misaligned address");
1317 case Mips::BEQZ16_MM:
1318 case Mips::BNEZ16_MM:
1319 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1320 Offset = Inst.getOperand(1);
1321 if (!Offset.isImm())
1322 break; // We'll deal with this situation later on when applying fixups.
1323 if (!isIntN(8, Offset.getImm()))
1324 return Error(IDLoc, "branch target out of range");
1325 if (OffsetToAlignment(Offset.getImm(), 2LL))
1326 return Error(IDLoc, "branch to misaligned address");
1331 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1332 // We still accept it but it is a normal nop.
1333 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1334 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1335 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1340 const unsigned Opcode = Inst.getOpcode();
1352 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1353 // The offset is handled above
1354 Opnd = Inst.getOperand(1);
1356 return Error(IDLoc, "expected immediate operand kind");
1357 Imm = Opnd.getImm();
1358 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1359 Opcode == Mips::BBIT1 ? 63 : 31))
1360 return Error(IDLoc, "immediate operand value out of range");
1362 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1364 Inst.getOperand(1).setImm(Imm - 32);
1372 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1374 Opnd = Inst.getOperand(3);
1376 return Error(IDLoc, "expected immediate operand kind");
1377 Imm = Opnd.getImm();
1378 if (Imm < 0 || Imm > 31)
1379 return Error(IDLoc, "immediate operand value out of range");
1381 Opnd = Inst.getOperand(2);
1383 return Error(IDLoc, "expected immediate operand kind");
1384 Imm = Opnd.getImm();
1385 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1386 Opcode == Mips::EXTS ? 63 : 31))
1387 return Error(IDLoc, "immediate operand value out of range");
1389 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1390 Inst.getOperand(2).setImm(Imm - 32);
1396 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1397 Opnd = Inst.getOperand(2);
1399 return Error(IDLoc, "expected immediate operand kind");
1400 Imm = Opnd.getImm();
1401 if (!isInt<10>(Imm))
1402 return Error(IDLoc, "immediate operand value out of range");
1407 if (MCID.mayLoad() || MCID.mayStore()) {
1408 // Check the offset of memory operand, if it is a symbol
1409 // reference or immediate we may have to expand instructions.
1410 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1411 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1412 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1413 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1414 MCOperand &Op = Inst.getOperand(i);
1416 int MemOffset = Op.getImm();
1417 if (MemOffset < -32768 || MemOffset > 32767) {
1418 // Offset can't exceed 16bit value.
1419 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1422 } else if (Op.isExpr()) {
1423 const MCExpr *Expr = Op.getExpr();
1424 if (Expr->getKind() == MCExpr::SymbolRef) {
1425 const MCSymbolRefExpr *SR =
1426 static_cast<const MCSymbolRefExpr *>(Expr);
1427 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1429 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1432 } else if (!isEvaluated(Expr)) {
1433 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1441 if (inMicroMipsMode()) {
1442 if (MCID.mayLoad()) {
1443 // Try to create 16-bit GP relative load instruction.
1444 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1445 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1446 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1447 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1448 MCOperand &Op = Inst.getOperand(i);
1450 int MemOffset = Op.getImm();
1451 MCOperand &DstReg = Inst.getOperand(0);
1452 MCOperand &BaseReg = Inst.getOperand(1);
1453 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1454 getContext().getRegisterInfo()->getRegClass(
1455 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1456 BaseReg.getReg() == Mips::GP) {
1458 TmpInst.setLoc(IDLoc);
1459 TmpInst.setOpcode(Mips::LWGP_MM);
1460 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1461 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1462 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1463 Instructions.push_back(TmpInst);
1471 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1476 switch (Inst.getOpcode()) {
1479 case Mips::ADDIUS5_MM:
1480 Opnd = Inst.getOperand(2);
1482 return Error(IDLoc, "expected immediate operand kind");
1483 Imm = Opnd.getImm();
1484 if (Imm < -8 || Imm > 7)
1485 return Error(IDLoc, "immediate operand value out of range");
1487 case Mips::ADDIUSP_MM:
1488 Opnd = Inst.getOperand(0);
1490 return Error(IDLoc, "expected immediate operand kind");
1491 Imm = Opnd.getImm();
1492 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1494 return Error(IDLoc, "immediate operand value out of range");
1496 case Mips::SLL16_MM:
1497 case Mips::SRL16_MM:
1498 Opnd = Inst.getOperand(2);
1500 return Error(IDLoc, "expected immediate operand kind");
1501 Imm = Opnd.getImm();
1502 if (Imm < 1 || Imm > 8)
1503 return Error(IDLoc, "immediate operand value out of range");
1506 Opnd = Inst.getOperand(1);
1508 return Error(IDLoc, "expected immediate operand kind");
1509 Imm = Opnd.getImm();
1510 if (Imm < -1 || Imm > 126)
1511 return Error(IDLoc, "immediate operand value out of range");
1513 case Mips::ADDIUR2_MM:
1514 Opnd = Inst.getOperand(2);
1516 return Error(IDLoc, "expected immediate operand kind");
1517 Imm = Opnd.getImm();
1518 if (!(Imm == 1 || Imm == -1 ||
1519 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1520 return Error(IDLoc, "immediate operand value out of range");
1522 case Mips::ADDIUR1SP_MM:
1523 Opnd = Inst.getOperand(1);
1525 return Error(IDLoc, "expected immediate operand kind");
1526 Imm = Opnd.getImm();
1527 if (OffsetToAlignment(Imm, 4LL))
1528 return Error(IDLoc, "misaligned immediate operand value");
1529 if (Imm < 0 || Imm > 255)
1530 return Error(IDLoc, "immediate operand value out of range");
1532 case Mips::ANDI16_MM:
1533 Opnd = Inst.getOperand(2);
1535 return Error(IDLoc, "expected immediate operand kind");
1536 Imm = Opnd.getImm();
1537 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1538 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1539 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1540 return Error(IDLoc, "immediate operand value out of range");
1542 case Mips::LBU16_MM:
1543 Opnd = Inst.getOperand(2);
1545 return Error(IDLoc, "expected immediate operand kind");
1546 Imm = Opnd.getImm();
1547 if (Imm < -1 || Imm > 14)
1548 return Error(IDLoc, "immediate operand value out of range");
1551 Opnd = Inst.getOperand(2);
1553 return Error(IDLoc, "expected immediate operand kind");
1554 Imm = Opnd.getImm();
1555 if (Imm < 0 || Imm > 15)
1556 return Error(IDLoc, "immediate operand value out of range");
1558 case Mips::LHU16_MM:
1560 Opnd = Inst.getOperand(2);
1562 return Error(IDLoc, "expected immediate operand kind");
1563 Imm = Opnd.getImm();
1564 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1565 return Error(IDLoc, "immediate operand value out of range");
1569 Opnd = Inst.getOperand(2);
1571 return Error(IDLoc, "expected immediate operand kind");
1572 Imm = Opnd.getImm();
1573 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1574 return Error(IDLoc, "immediate operand value out of range");
1578 Opnd = Inst.getOperand(2);
1580 return Error(IDLoc, "expected immediate operand kind");
1581 Imm = Opnd.getImm();
1582 if (!isUInt<5>(Imm))
1583 return Error(IDLoc, "immediate operand value out of range");
1585 case Mips::ADDIUPC_MM:
1586 MCOperand Opnd = Inst.getOperand(1);
1588 return Error(IDLoc, "expected immediate operand kind");
1589 int Imm = Opnd.getImm();
1590 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1591 return Error(IDLoc, "immediate operand value out of range");
1596 if (needsExpansion(Inst)) {
1597 if (expandInstruction(Inst, IDLoc, Instructions))
1600 Instructions.push_back(Inst);
1602 // If this instruction has a delay slot and .set reorder is active,
1603 // emit a NOP after it.
1604 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1605 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1610 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1612 switch (Inst.getOpcode()) {
1613 case Mips::LoadImm32:
1614 case Mips::LoadImm64:
1615 case Mips::LoadAddrImm32:
1616 case Mips::LoadAddrReg32:
1617 case Mips::B_MM_Pseudo:
1620 case Mips::JalOneReg:
1621 case Mips::JalTwoReg:
1628 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1629 SmallVectorImpl<MCInst> &Instructions) {
1630 switch (Inst.getOpcode()) {
1631 default: llvm_unreachable("unimplemented expansion");
1632 case Mips::LoadImm32:
1633 return expandLoadImm(Inst, true, IDLoc, Instructions);
1634 case Mips::LoadImm64:
1635 return expandLoadImm(Inst, false, IDLoc, Instructions);
1636 case Mips::LoadAddrImm32:
1637 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1638 case Mips::LoadAddrReg32:
1639 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1640 case Mips::B_MM_Pseudo:
1641 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1644 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1645 case Mips::JalOneReg:
1646 case Mips::JalTwoReg:
1647 return expandJalWithRegs(Inst, IDLoc, Instructions);
1652 template <unsigned ShiftAmount>
1653 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1654 SmallVectorImpl<MCInst> &Instructions) {
1656 if (ShiftAmount >= 32) {
1657 tmpInst.setOpcode(Mips::DSLL32);
1658 tmpInst.addOperand(MCOperand::createReg(RegNo));
1659 tmpInst.addOperand(MCOperand::createReg(RegNo));
1660 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1661 tmpInst.setLoc(IDLoc);
1662 Instructions.push_back(tmpInst);
1664 } else if (ShiftAmount > 0) {
1665 tmpInst.setOpcode(Mips::DSLL);
1666 tmpInst.addOperand(MCOperand::createReg(RegNo));
1667 tmpInst.addOperand(MCOperand::createReg(RegNo));
1668 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1669 tmpInst.setLoc(IDLoc);
1670 Instructions.push_back(tmpInst);
1673 // There's no need for an ORi if the immediate is 0.
1674 if (Operand.isImm() && Operand.getImm() == 0)
1677 tmpInst.setOpcode(Mips::ORi);
1678 tmpInst.addOperand(MCOperand::createReg(RegNo));
1679 tmpInst.addOperand(MCOperand::createReg(RegNo));
1680 tmpInst.addOperand(Operand);
1681 tmpInst.setLoc(IDLoc);
1682 Instructions.push_back(tmpInst);
1685 template <unsigned ShiftAmount>
1686 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1687 SmallVectorImpl<MCInst> &Instructions) {
1688 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1693 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1694 SmallVectorImpl<MCInst> &Instructions) {
1695 // Create a JALR instruction which is going to replace the pseudo-JAL.
1697 JalrInst.setLoc(IDLoc);
1698 const MCOperand FirstRegOp = Inst.getOperand(0);
1699 const unsigned Opcode = Inst.getOpcode();
1701 if (Opcode == Mips::JalOneReg) {
1702 // jal $rs => jalr $rs
1703 if (inMicroMipsMode()) {
1704 JalrInst.setOpcode(Mips::JALR16_MM);
1705 JalrInst.addOperand(FirstRegOp);
1707 JalrInst.setOpcode(Mips::JALR);
1708 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1709 JalrInst.addOperand(FirstRegOp);
1711 } else if (Opcode == Mips::JalTwoReg) {
1712 // jal $rd, $rs => jalr $rd, $rs
1713 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1714 JalrInst.addOperand(FirstRegOp);
1715 const MCOperand SecondRegOp = Inst.getOperand(1);
1716 JalrInst.addOperand(SecondRegOp);
1718 Instructions.push_back(JalrInst);
1720 // If .set reorder is active, emit a NOP after it.
1721 if (AssemblerOptions.back()->isReorder()) {
1722 // This is a 32-bit NOP because these 2 pseudo-instructions
1723 // do not have a short delay slot.
1725 NopInst.setOpcode(Mips::SLL);
1726 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1727 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1728 NopInst.addOperand(MCOperand::createImm(0));
1729 Instructions.push_back(NopInst);
1735 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1736 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1737 SmallVectorImpl<MCInst> &Instructions) {
1738 if (!Is32BitImm && !isGP64bit()) {
1739 Error(IDLoc, "instruction requires a 64-bit architecture");
1743 bool UseSrcReg = false;
1744 if (SrcReg != Mips::NoRegister)
1749 tmpInst.setLoc(IDLoc);
1750 // FIXME: gas has a special case for values that are 000...1111, which
1751 // becomes a li -1 and then a dsrl
1752 if (0 <= ImmValue && ImmValue <= 65535) {
1753 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1754 // li d,j => ori d,$zero,j
1756 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1757 tmpInst.setOpcode(Mips::ORi);
1758 tmpInst.addOperand(MCOperand::createReg(DstReg));
1759 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1760 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1761 Instructions.push_back(tmpInst);
1762 } else if (ImmValue < 0 && ImmValue >= -32768) {
1763 // For negative signed 16-bit values (-32768 <= j < 0):
1764 // li d,j => addiu d,$zero,j
1766 SrcReg = Mips::ZERO;
1767 tmpInst.setOpcode(Mips::ADDiu);
1768 tmpInst.addOperand(MCOperand::createReg(DstReg));
1769 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1770 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1771 Instructions.push_back(tmpInst);
1772 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1773 warnIfNoMacro(IDLoc);
1775 // For all other values which are representable as a 32-bit integer:
1776 // li d,j => lui d,hi16(j)
1778 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1779 uint16_t Bits15To0 = ImmValue & 0xffff;
1781 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1782 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1784 tmpInst.setOpcode(Mips::ORi);
1785 tmpInst.addOperand(MCOperand::createReg(DstReg));
1786 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1787 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1788 tmpInst.setLoc(IDLoc);
1789 Instructions.push_back(tmpInst);
1790 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1791 createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
1793 tmpInst.setOpcode(Mips::LUi);
1794 tmpInst.addOperand(MCOperand::createReg(DstReg));
1795 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1796 Instructions.push_back(tmpInst);
1798 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1801 createAddu(DstReg, DstReg, SrcReg, Instructions);
1803 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1805 Error(IDLoc, "instruction requires a 32-bit immediate");
1808 warnIfNoMacro(IDLoc);
1810 // <------- lo32 ------>
1811 // <------- hi32 ------>
1812 // <- hi16 -> <- lo16 ->
1813 // _________________________________
1815 // | 16-bits | 16-bits | 16-bits |
1816 // |__________|__________|__________|
1818 // For any 64-bit value that is representable as a 48-bit integer:
1819 // li d,j => lui d,hi16(j)
1820 // ori d,d,hi16(lo32(j))
1822 // ori d,d,lo16(lo32(j))
1823 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1824 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1825 uint16_t Bits15To0 = ImmValue & 0xffff;
1827 tmpInst.setOpcode(Mips::LUi);
1828 tmpInst.addOperand(MCOperand::createReg(DstReg));
1829 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1830 Instructions.push_back(tmpInst);
1831 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1832 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1835 createAddu(DstReg, DstReg, SrcReg, Instructions);
1839 Error(IDLoc, "instruction requires a 32-bit immediate");
1842 warnIfNoMacro(IDLoc);
1844 // <------- hi32 ------> <------- lo32 ------>
1845 // <- hi16 -> <- lo16 ->
1846 // ___________________________________________
1848 // | 16-bits | 16-bits | 16-bits | 16-bits |
1849 // |__________|__________|__________|__________|
1851 // For all other values which are representable as a 64-bit integer:
1852 // li d,j => lui d,hi16(j)
1853 // ori d,d,lo16(hi32(j))
1855 // ori d,d,hi16(lo32(j))
1857 // ori d,d,lo16(lo32(j))
1858 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1859 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1860 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1861 uint16_t Bits15To0 = ImmValue & 0xffff;
1863 tmpInst.setOpcode(Mips::LUi);
1864 tmpInst.addOperand(MCOperand::createReg(DstReg));
1865 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1866 Instructions.push_back(tmpInst);
1867 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1869 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1870 // two left shifts of 16 bits.
1871 if (Bits31To16 == 0) {
1872 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1874 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1875 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1879 createAddu(DstReg, DstReg, SrcReg, Instructions);
1884 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1885 SmallVectorImpl<MCInst> &Instructions) {
1886 const MCOperand &ImmOp = Inst.getOperand(1);
1887 assert(ImmOp.isImm() && "expected immediate operand kind");
1888 const MCOperand &DstRegOp = Inst.getOperand(0);
1889 assert(DstRegOp.isReg() && "expected register operand kind");
1891 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1892 Is32BitImm, IDLoc, Instructions))
1899 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1900 SmallVectorImpl<MCInst> &Instructions) {
1901 const MCOperand &DstRegOp = Inst.getOperand(0);
1902 assert(DstRegOp.isReg() && "expected register operand kind");
1904 const MCOperand &ImmOp = Inst.getOperand(2);
1905 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1906 "expected immediate operand kind");
1907 if (!ImmOp.isImm()) {
1908 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1911 const MCOperand &SrcRegOp = Inst.getOperand(1);
1912 assert(SrcRegOp.isReg() && "expected register operand kind");
1914 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1915 Is32BitImm, IDLoc, Instructions))
1922 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1923 SmallVectorImpl<MCInst> &Instructions) {
1924 const MCOperand &DstRegOp = Inst.getOperand(0);
1925 assert(DstRegOp.isReg() && "expected register operand kind");
1927 const MCOperand &ImmOp = Inst.getOperand(1);
1928 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1929 "expected immediate operand kind");
1930 if (!ImmOp.isImm()) {
1931 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1935 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1936 Is32BitImm, IDLoc, Instructions))
1942 void MipsAsmParser::expandLoadAddressSym(
1943 const MCOperand &DstRegOp, const MCOperand &SymOp, bool Is32BitSym,
1944 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1945 warnIfNoMacro(IDLoc);
1947 if (Is32BitSym && isABI_N64())
1948 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1951 unsigned RegNo = DstRegOp.getReg();
1952 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1953 const MCSymbolRefExpr *HiExpr =
1954 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1955 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1956 const MCSymbolRefExpr *LoExpr =
1957 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1958 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1960 // If it's a 64-bit architecture, expand to:
1961 // la d,sym => lui d,highest(sym)
1962 // ori d,d,higher(sym)
1964 // ori d,d,hi16(sym)
1966 // ori d,d,lo16(sym)
1967 const MCSymbolRefExpr *HighestExpr =
1968 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1969 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1970 const MCSymbolRefExpr *HigherExpr =
1971 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1972 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1974 tmpInst.setOpcode(Mips::LUi);
1975 tmpInst.addOperand(MCOperand::createReg(RegNo));
1976 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1977 Instructions.push_back(tmpInst);
1979 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), RegNo, SMLoc(),
1981 createLShiftOri<16>(MCOperand::createExpr(HiExpr), RegNo, SMLoc(),
1983 createLShiftOri<16>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1986 // Otherwise, expand to:
1987 // la d,sym => lui d,hi16(sym)
1988 // ori d,d,lo16(sym)
1989 tmpInst.setOpcode(Mips::LUi);
1990 tmpInst.addOperand(MCOperand::createReg(RegNo));
1991 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
1992 Instructions.push_back(tmpInst);
1994 createLShiftOri<0>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1999 bool MipsAsmParser::expandUncondBranchMMPseudo(
2000 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2001 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2002 "unexpected number of operands");
2004 MCOperand Offset = Inst.getOperand(0);
2005 if (Offset.isExpr()) {
2007 Inst.setOpcode(Mips::BEQ_MM);
2008 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2009 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2010 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2012 assert(Offset.isImm() && "expected immediate operand kind");
2013 if (isIntN(11, Offset.getImm())) {
2014 // If offset fits into 11 bits then this instruction becomes microMIPS
2015 // 16-bit unconditional branch instruction.
2016 Inst.setOpcode(Mips::B16_MM);
2018 if (!isIntN(17, Offset.getImm()))
2019 Error(IDLoc, "branch target out of range");
2020 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2021 Error(IDLoc, "branch to misaligned address");
2023 Inst.setOpcode(Mips::BEQ_MM);
2024 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2025 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2026 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2029 Instructions.push_back(Inst);
2031 // If .set reorder is active, emit a NOP after the branch instruction.
2032 if (AssemblerOptions.back()->isReorder())
2033 createNop(true, IDLoc, Instructions);
2038 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2039 SmallVectorImpl<MCInst> &Instructions,
2040 bool isLoad, bool isImmOpnd) {
2041 const MCSymbolRefExpr *SR;
2043 unsigned ImmOffset, HiOffset, LoOffset;
2044 const MCExpr *ExprOffset;
2046 // 1st operand is either the source or destination register.
2047 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2048 unsigned RegOpNum = Inst.getOperand(0).getReg();
2049 // 2nd operand is the base register.
2050 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2051 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2052 // 3rd operand is either an immediate or expression.
2054 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2055 ImmOffset = Inst.getOperand(2).getImm();
2056 LoOffset = ImmOffset & 0x0000ffff;
2057 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2058 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2059 if (LoOffset & 0x8000)
2062 ExprOffset = Inst.getOperand(2).getExpr();
2063 // All instructions will have the same location.
2064 TempInst.setLoc(IDLoc);
2065 // These are some of the types of expansions we perform here:
2066 // 1) lw $8, sym => lui $8, %hi(sym)
2067 // lw $8, %lo(sym)($8)
2068 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2070 // lw $8, %lo(offset)($9)
2071 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2073 // lw $8, %lo(offset)($at)
2074 // 4) sw $8, sym => lui $at, %hi(sym)
2075 // sw $8, %lo(sym)($at)
2076 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2078 // sw $8, %lo(offset)($at)
2079 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2080 // ldc1 $f0, %lo(sym)($at)
2082 // For load instructions we can use the destination register as a temporary
2083 // if base and dst are different (examples 1 and 2) and if the base register
2084 // is general purpose otherwise we must use $at (example 6) and error if it's
2085 // not available. For stores we must use $at (examples 4 and 5) because we
2086 // must not clobber the source register setting up the offset.
2087 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2088 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2089 unsigned RegClassIDOp0 =
2090 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2091 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2092 (RegClassIDOp0 == Mips::GPR64RegClassID);
2093 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2094 TmpRegNum = RegOpNum;
2096 // At this point we need AT to perform the expansions and we exit if it is
2098 TmpRegNum = getATReg(IDLoc);
2103 TempInst.setOpcode(Mips::LUi);
2104 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2106 TempInst.addOperand(MCOperand::createImm(HiOffset));
2108 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2109 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2110 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2111 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2113 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2115 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2116 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2119 // Add the instruction to the list.
2120 Instructions.push_back(TempInst);
2121 // Prepare TempInst for next instruction.
2123 // Add temp register to base.
2124 if (BaseRegNum != Mips::ZERO) {
2125 TempInst.setOpcode(Mips::ADDu);
2126 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2127 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2128 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2129 Instructions.push_back(TempInst);
2132 // And finally, create original instruction with low part
2133 // of offset and new base.
2134 TempInst.setOpcode(Inst.getOpcode());
2135 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2136 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2138 TempInst.addOperand(MCOperand::createImm(LoOffset));
2140 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2141 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2142 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2144 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2146 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2147 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2150 Instructions.push_back(TempInst);
2155 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2156 SmallVectorImpl<MCInst> &Instructions) {
2157 unsigned OpNum = Inst.getNumOperands();
2158 unsigned Opcode = Inst.getOpcode();
2159 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2161 assert (Inst.getOperand(OpNum - 1).isImm() &&
2162 Inst.getOperand(OpNum - 2).isReg() &&
2163 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2165 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2166 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2167 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2168 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2169 // It can be implemented as SWM16 or LWM16 instruction.
2170 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2172 Inst.setOpcode(NewOpcode);
2173 Instructions.push_back(Inst);
2177 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2178 SmallVectorImpl<MCInst> &Instructions) {
2180 if (hasShortDelaySlot) {
2181 NopInst.setOpcode(Mips::MOVE16_MM);
2182 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2183 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2185 NopInst.setOpcode(Mips::SLL);
2186 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2187 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2188 NopInst.addOperand(MCOperand::createImm(0));
2190 Instructions.push_back(NopInst);
2193 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2195 SmallVectorImpl<MCInst> &Instructions) {
2197 AdduInst.setOpcode(Mips::ADDu);
2198 AdduInst.addOperand(MCOperand::createReg(DstReg));
2199 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2200 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2201 Instructions.push_back(AdduInst);
2204 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2205 // As described by the Mips32r2 spec, the registers Rd and Rs for
2206 // jalr.hb must be different.
2207 unsigned Opcode = Inst.getOpcode();
2209 if (Opcode == Mips::JALR_HB &&
2210 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2211 return Match_RequiresDifferentSrcAndDst;
2213 return Match_Success;
2216 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2217 OperandVector &Operands,
2219 uint64_t &ErrorInfo,
2220 bool MatchingInlineAsm) {
2223 SmallVector<MCInst, 8> Instructions;
2224 unsigned MatchResult =
2225 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2227 switch (MatchResult) {
2228 case Match_Success: {
2229 if (processInstruction(Inst, IDLoc, Instructions))
2231 for (unsigned i = 0; i < Instructions.size(); i++)
2232 Out.EmitInstruction(Instructions[i], STI);
2235 case Match_MissingFeature:
2236 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2238 case Match_InvalidOperand: {
2239 SMLoc ErrorLoc = IDLoc;
2240 if (ErrorInfo != ~0ULL) {
2241 if (ErrorInfo >= Operands.size())
2242 return Error(IDLoc, "too few operands for instruction");
2244 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2245 if (ErrorLoc == SMLoc())
2249 return Error(ErrorLoc, "invalid operand for instruction");
2251 case Match_MnemonicFail:
2252 return Error(IDLoc, "invalid instruction");
2253 case Match_RequiresDifferentSrcAndDst:
2254 return Error(IDLoc, "source and destination must be different");
2257 llvm_unreachable("Implement any new match types added!");
2260 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2261 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2262 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2263 ") without \".set noat\"");
2266 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2267 if (!AssemblerOptions.back()->isMacro())
2268 Warning(Loc, "macro instruction expanded into multiple instructions");
2272 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2273 SMRange Range, bool ShowColors) {
2274 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2275 Range, SMFixIt(Range, FixMsg),
2279 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2282 CC = StringSwitch<unsigned>(Name)
2318 if (!(isABI_N32() || isABI_N64()))
2321 if (12 <= CC && CC <= 15) {
2322 // Name is one of t4-t7
2323 AsmToken RegTok = getLexer().peekTok();
2324 SMRange RegRange = RegTok.getLocRange();
2326 StringRef FixedName = StringSwitch<StringRef>(Name)
2332 assert(FixedName != "" && "Register name is not one of t4-t7.");
2334 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2335 "Did you mean $" + FixedName + "?", RegRange);
2338 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2339 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2340 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2341 if (8 <= CC && CC <= 11)
2345 CC = StringSwitch<unsigned>(Name)
2357 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2360 CC = StringSwitch<unsigned>(Name)
2361 .Case("hwr_cpunum", 0)
2362 .Case("hwr_synci_step", 1)
2364 .Case("hwr_ccres", 3)
2365 .Case("hwr_ulr", 29)
2371 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2373 if (Name[0] == 'f') {
2374 StringRef NumString = Name.substr(1);
2376 if (NumString.getAsInteger(10, IntVal))
2377 return -1; // This is not an integer.
2378 if (IntVal > 31) // Maximum index for fpu register.
2385 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2387 if (Name.startswith("fcc")) {
2388 StringRef NumString = Name.substr(3);
2390 if (NumString.getAsInteger(10, IntVal))
2391 return -1; // This is not an integer.
2392 if (IntVal > 7) // There are only 8 fcc registers.
2399 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2401 if (Name.startswith("ac")) {
2402 StringRef NumString = Name.substr(2);
2404 if (NumString.getAsInteger(10, IntVal))
2405 return -1; // This is not an integer.
2406 if (IntVal > 3) // There are only 3 acc registers.
2413 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2416 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2425 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2428 CC = StringSwitch<unsigned>(Name)
2431 .Case("msaaccess", 2)
2433 .Case("msamodify", 4)
2434 .Case("msarequest", 5)
2436 .Case("msaunmap", 7)
2442 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2443 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2445 reportParseError(Loc,
2446 "pseudo-instruction requires $at, which is not available");
2449 unsigned AT = getReg(
2450 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2454 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2455 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2458 unsigned MipsAsmParser::getGPR(int RegNo) {
2459 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2463 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2465 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2468 return getReg(RegClass, RegNum);
2471 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2472 MCAsmParser &Parser = getParser();
2473 DEBUG(dbgs() << "parseOperand\n");
2475 // Check if the current operand has a custom associated parser, if so, try to
2476 // custom parse the operand, or fallback to the general approach.
2477 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2478 if (ResTy == MatchOperand_Success)
2480 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2481 // there was a match, but an error occurred, in which case, just return that
2482 // the operand parsing failed.
2483 if (ResTy == MatchOperand_ParseFail)
2486 DEBUG(dbgs() << ".. Generic Parser\n");
2488 switch (getLexer().getKind()) {
2490 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2492 case AsmToken::Dollar: {
2493 // Parse the register.
2494 SMLoc S = Parser.getTok().getLoc();
2496 // Almost all registers have been parsed by custom parsers. There is only
2497 // one exception to this. $zero (and it's alias $0) will reach this point
2498 // for div, divu, and similar instructions because it is not an operand
2499 // to the instruction definition but an explicit register. Special case
2500 // this situation for now.
2501 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2504 // Maybe it is a symbol reference.
2505 StringRef Identifier;
2506 if (Parser.parseIdentifier(Identifier))
2509 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2510 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2511 // Otherwise create a symbol reference.
2513 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2515 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2518 // Else drop to expression parsing.
2519 case AsmToken::LParen:
2520 case AsmToken::Minus:
2521 case AsmToken::Plus:
2522 case AsmToken::Integer:
2523 case AsmToken::Tilde:
2524 case AsmToken::String: {
2525 DEBUG(dbgs() << ".. generic integer\n");
2526 OperandMatchResultTy ResTy = parseImm(Operands);
2527 return ResTy != MatchOperand_Success;
2529 case AsmToken::Percent: {
2530 // It is a symbol reference or constant expression.
2531 const MCExpr *IdVal;
2532 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2533 if (parseRelocOperand(IdVal))
2536 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2538 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2540 } // case AsmToken::Percent
2541 } // switch(getLexer().getKind())
2545 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2546 StringRef RelocStr) {
2548 // Check the type of the expression.
2549 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2550 // It's a constant, evaluate reloc value.
2552 switch (getVariantKind(RelocStr)) {
2553 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2554 // Get the 1st 16-bits.
2555 Val = MCE->getValue() & 0xffff;
2557 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2558 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2559 // 16 bits being negative.
2560 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2562 case MCSymbolRefExpr::VK_Mips_HIGHER:
2563 // Get the 3rd 16-bits.
2564 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2566 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2567 // Get the 4th 16-bits.
2568 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2571 report_fatal_error("unsupported reloc value");
2573 return MCConstantExpr::create(Val, getContext());
2576 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2577 // It's a symbol, create a symbolic expression from the symbol.
2578 StringRef Symbol = MSRE->getSymbol().getName();
2579 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2580 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
2584 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2585 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2587 // Try to create target expression.
2588 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2589 return MipsMCExpr::create(VK, Expr, getContext());
2591 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2592 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2593 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
2597 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2598 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2599 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
2602 // Just return the original expression.
2606 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2608 switch (Expr->getKind()) {
2609 case MCExpr::Constant:
2611 case MCExpr::SymbolRef:
2612 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2613 case MCExpr::Binary:
2614 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2615 if (!isEvaluated(BE->getLHS()))
2617 return isEvaluated(BE->getRHS());
2620 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2621 case MCExpr::Target:
2627 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2628 MCAsmParser &Parser = getParser();
2629 Parser.Lex(); // Eat the % token.
2630 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2631 if (Tok.isNot(AsmToken::Identifier))
2634 std::string Str = Tok.getIdentifier();
2636 Parser.Lex(); // Eat the identifier.
2637 // Now make an expression from the rest of the operand.
2638 const MCExpr *IdVal;
2641 if (getLexer().getKind() == AsmToken::LParen) {
2643 Parser.Lex(); // Eat the '(' token.
2644 if (getLexer().getKind() == AsmToken::Percent) {
2645 Parser.Lex(); // Eat the % token.
2646 const AsmToken &nextTok = Parser.getTok();
2647 if (nextTok.isNot(AsmToken::Identifier))
2650 Str += nextTok.getIdentifier();
2651 Parser.Lex(); // Eat the identifier.
2652 if (getLexer().getKind() != AsmToken::LParen)
2657 if (getParser().parseParenExpression(IdVal, EndLoc))
2660 while (getLexer().getKind() == AsmToken::RParen)
2661 Parser.Lex(); // Eat the ')' token.
2664 return true; // Parenthesis must follow the relocation operand.
2666 Res = evaluateRelocExpr(IdVal, Str);
2670 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2672 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2673 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2674 if (ResTy == MatchOperand_Success) {
2675 assert(Operands.size() == 1);
2676 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2677 StartLoc = Operand.getStartLoc();
2678 EndLoc = Operand.getEndLoc();
2680 // AFAIK, we only support numeric registers and named GPR's in CFI
2682 // Don't worry about eating tokens before failing. Using an unrecognised
2683 // register is a parse error.
2684 if (Operand.isGPRAsmReg()) {
2685 // Resolve to GPR32 or GPR64 appropriately.
2686 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2689 return (RegNo == (unsigned)-1);
2692 assert(Operands.size() == 0);
2693 return (RegNo == (unsigned)-1);
2696 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2697 MCAsmParser &Parser = getParser();
2701 while (getLexer().getKind() == AsmToken::LParen)
2704 switch (getLexer().getKind()) {
2707 case AsmToken::Identifier:
2708 case AsmToken::LParen:
2709 case AsmToken::Integer:
2710 case AsmToken::Minus:
2711 case AsmToken::Plus:
2713 Result = getParser().parseParenExpression(Res, S);
2715 Result = (getParser().parseExpression(Res));
2716 while (getLexer().getKind() == AsmToken::RParen)
2719 case AsmToken::Percent:
2720 Result = parseRelocOperand(Res);
2725 MipsAsmParser::OperandMatchResultTy
2726 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2727 MCAsmParser &Parser = getParser();
2728 DEBUG(dbgs() << "parseMemOperand\n");
2729 const MCExpr *IdVal = nullptr;
2731 bool isParenExpr = false;
2732 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2733 // First operand is the offset.
2734 S = Parser.getTok().getLoc();
2736 if (getLexer().getKind() == AsmToken::LParen) {
2741 if (getLexer().getKind() != AsmToken::Dollar) {
2742 if (parseMemOffset(IdVal, isParenExpr))
2743 return MatchOperand_ParseFail;
2745 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2746 if (Tok.isNot(AsmToken::LParen)) {
2747 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2748 if (Mnemonic.getToken() == "la") {
2750 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2751 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2752 return MatchOperand_Success;
2754 if (Tok.is(AsmToken::EndOfStatement)) {
2756 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2758 // Zero register assumed, add a memory operand with ZERO as its base.
2759 // "Base" will be managed by k_Memory.
2760 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2763 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2764 return MatchOperand_Success;
2766 Error(Parser.getTok().getLoc(), "'(' expected");
2767 return MatchOperand_ParseFail;
2770 Parser.Lex(); // Eat the '(' token.
2773 Res = parseAnyRegister(Operands);
2774 if (Res != MatchOperand_Success)
2777 if (Parser.getTok().isNot(AsmToken::RParen)) {
2778 Error(Parser.getTok().getLoc(), "')' expected");
2779 return MatchOperand_ParseFail;
2782 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2784 Parser.Lex(); // Eat the ')' token.
2787 IdVal = MCConstantExpr::create(0, getContext());
2789 // Replace the register operand with the memory operand.
2790 std::unique_ptr<MipsOperand> op(
2791 static_cast<MipsOperand *>(Operands.back().release()));
2792 // Remove the register from the operands.
2793 // "op" will be managed by k_Memory.
2794 Operands.pop_back();
2795 // Add the memory operand.
2796 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2798 if (IdVal->evaluateAsAbsolute(Imm))
2799 IdVal = MCConstantExpr::create(Imm, getContext());
2800 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2801 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2805 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2806 return MatchOperand_Success;
2809 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2810 MCAsmParser &Parser = getParser();
2811 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
2813 SMLoc S = Parser.getTok().getLoc();
2815 if (Sym->isVariable())
2816 Expr = Sym->getVariableValue();
2819 if (Expr->getKind() == MCExpr::SymbolRef) {
2820 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2821 StringRef DefSymbol = Ref->getSymbol().getName();
2822 if (DefSymbol.startswith("$")) {
2823 OperandMatchResultTy ResTy =
2824 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2825 if (ResTy == MatchOperand_Success) {
2828 } else if (ResTy == MatchOperand_ParseFail)
2829 llvm_unreachable("Should never ParseFail");
2832 } else if (Expr->getKind() == MCExpr::Constant) {
2834 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2836 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2843 MipsAsmParser::OperandMatchResultTy
2844 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2845 StringRef Identifier,
2847 int Index = matchCPURegisterName(Identifier);
2849 Operands.push_back(MipsOperand::createGPRReg(
2850 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2851 return MatchOperand_Success;
2854 Index = matchHWRegsRegisterName(Identifier);
2856 Operands.push_back(MipsOperand::createHWRegsReg(
2857 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2858 return MatchOperand_Success;
2861 Index = matchFPURegisterName(Identifier);
2863 Operands.push_back(MipsOperand::createFGRReg(
2864 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2865 return MatchOperand_Success;
2868 Index = matchFCCRegisterName(Identifier);
2870 Operands.push_back(MipsOperand::createFCCReg(
2871 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2872 return MatchOperand_Success;
2875 Index = matchACRegisterName(Identifier);
2877 Operands.push_back(MipsOperand::createACCReg(
2878 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2879 return MatchOperand_Success;
2882 Index = matchMSA128RegisterName(Identifier);
2884 Operands.push_back(MipsOperand::createMSA128Reg(
2885 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2886 return MatchOperand_Success;
2889 Index = matchMSA128CtrlRegisterName(Identifier);
2891 Operands.push_back(MipsOperand::createMSACtrlReg(
2892 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2893 return MatchOperand_Success;
2896 return MatchOperand_NoMatch;
2899 MipsAsmParser::OperandMatchResultTy
2900 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2901 MCAsmParser &Parser = getParser();
2902 auto Token = Parser.getLexer().peekTok(false);
2904 if (Token.is(AsmToken::Identifier)) {
2905 DEBUG(dbgs() << ".. identifier\n");
2906 StringRef Identifier = Token.getIdentifier();
2907 OperandMatchResultTy ResTy =
2908 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2910 } else if (Token.is(AsmToken::Integer)) {
2911 DEBUG(dbgs() << ".. integer\n");
2912 Operands.push_back(MipsOperand::createNumericReg(
2913 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2915 return MatchOperand_Success;
2918 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2920 return MatchOperand_NoMatch;
2923 MipsAsmParser::OperandMatchResultTy
2924 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2925 MCAsmParser &Parser = getParser();
2926 DEBUG(dbgs() << "parseAnyRegister\n");
2928 auto Token = Parser.getTok();
2930 SMLoc S = Token.getLoc();
2932 if (Token.isNot(AsmToken::Dollar)) {
2933 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2934 if (Token.is(AsmToken::Identifier)) {
2935 if (searchSymbolAlias(Operands))
2936 return MatchOperand_Success;
2938 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2939 return MatchOperand_NoMatch;
2941 DEBUG(dbgs() << ".. $\n");
2943 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2944 if (ResTy == MatchOperand_Success) {
2946 Parser.Lex(); // identifier
2951 MipsAsmParser::OperandMatchResultTy
2952 MipsAsmParser::parseImm(OperandVector &Operands) {
2953 MCAsmParser &Parser = getParser();
2954 switch (getLexer().getKind()) {
2956 return MatchOperand_NoMatch;
2957 case AsmToken::LParen:
2958 case AsmToken::Minus:
2959 case AsmToken::Plus:
2960 case AsmToken::Integer:
2961 case AsmToken::Tilde:
2962 case AsmToken::String:
2966 const MCExpr *IdVal;
2967 SMLoc S = Parser.getTok().getLoc();
2968 if (getParser().parseExpression(IdVal))
2969 return MatchOperand_ParseFail;
2971 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2972 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2973 return MatchOperand_Success;
2976 MipsAsmParser::OperandMatchResultTy
2977 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2978 MCAsmParser &Parser = getParser();
2979 DEBUG(dbgs() << "parseJumpTarget\n");
2981 SMLoc S = getLexer().getLoc();
2983 // Integers and expressions are acceptable
2984 OperandMatchResultTy ResTy = parseImm(Operands);
2985 if (ResTy != MatchOperand_NoMatch)
2988 // Registers are a valid target and have priority over symbols.
2989 ResTy = parseAnyRegister(Operands);
2990 if (ResTy != MatchOperand_NoMatch)
2993 const MCExpr *Expr = nullptr;
2994 if (Parser.parseExpression(Expr)) {
2995 // We have no way of knowing if a symbol was consumed so we must ParseFail
2996 return MatchOperand_ParseFail;
2999 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3000 return MatchOperand_Success;
3003 MipsAsmParser::OperandMatchResultTy
3004 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3005 MCAsmParser &Parser = getParser();
3006 const MCExpr *IdVal;
3007 // If the first token is '$' we may have register operand.
3008 if (Parser.getTok().is(AsmToken::Dollar))
3009 return MatchOperand_NoMatch;
3010 SMLoc S = Parser.getTok().getLoc();
3011 if (getParser().parseExpression(IdVal))
3012 return MatchOperand_ParseFail;
3013 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3014 assert(MCE && "Unexpected MCExpr type.");
3015 int64_t Val = MCE->getValue();
3016 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3017 Operands.push_back(MipsOperand::CreateImm(
3018 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3019 return MatchOperand_Success;
3022 MipsAsmParser::OperandMatchResultTy
3023 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3024 MCAsmParser &Parser = getParser();
3025 switch (getLexer().getKind()) {
3027 return MatchOperand_NoMatch;
3028 case AsmToken::LParen:
3029 case AsmToken::Plus:
3030 case AsmToken::Minus:
3031 case AsmToken::Integer:
3036 SMLoc S = Parser.getTok().getLoc();
3038 if (getParser().parseExpression(Expr))
3039 return MatchOperand_ParseFail;
3042 if (!Expr->evaluateAsAbsolute(Val)) {
3043 Error(S, "expected immediate value");
3044 return MatchOperand_ParseFail;
3047 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3048 // and because the CPU always adds one to the immediate field, the allowed
3049 // range becomes 1..4. We'll only check the range here and will deal
3050 // with the addition/subtraction when actually decoding/encoding
3052 if (Val < 1 || Val > 4) {
3053 Error(S, "immediate not in range (1..4)");
3054 return MatchOperand_ParseFail;
3058 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3059 return MatchOperand_Success;
3062 MipsAsmParser::OperandMatchResultTy
3063 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3064 MCAsmParser &Parser = getParser();
3065 SmallVector<unsigned, 10> Regs;
3067 unsigned PrevReg = Mips::NoRegister;
3068 bool RegRange = false;
3069 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3071 if (Parser.getTok().isNot(AsmToken::Dollar))
3072 return MatchOperand_ParseFail;
3074 SMLoc S = Parser.getTok().getLoc();
3075 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3076 SMLoc E = getLexer().getLoc();
3077 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3078 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3080 // Remove last register operand because registers from register range
3081 // should be inserted first.
3082 if (RegNo == Mips::RA) {
3083 Regs.push_back(RegNo);
3085 unsigned TmpReg = PrevReg + 1;
3086 while (TmpReg <= RegNo) {
3087 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3088 Error(E, "invalid register operand");
3089 return MatchOperand_ParseFail;
3093 Regs.push_back(TmpReg++);
3099 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3100 (RegNo != Mips::RA)) {
3101 Error(E, "$16 or $31 expected");
3102 return MatchOperand_ParseFail;
3103 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3104 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3105 Error(E, "invalid register operand");
3106 return MatchOperand_ParseFail;
3107 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3108 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3109 Error(E, "consecutive register numbers expected");
3110 return MatchOperand_ParseFail;
3113 Regs.push_back(RegNo);
3116 if (Parser.getTok().is(AsmToken::Minus))
3119 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3120 !Parser.getTok().isNot(AsmToken::Comma)) {
3121 Error(E, "',' or '-' expected");
3122 return MatchOperand_ParseFail;
3125 Lex(); // Consume comma or minus
3126 if (Parser.getTok().isNot(AsmToken::Dollar))
3132 SMLoc E = Parser.getTok().getLoc();
3133 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3134 parseMemOperand(Operands);
3135 return MatchOperand_Success;
3138 MipsAsmParser::OperandMatchResultTy
3139 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3140 MCAsmParser &Parser = getParser();
3142 SMLoc S = Parser.getTok().getLoc();
3143 if (parseAnyRegister(Operands) != MatchOperand_Success)
3144 return MatchOperand_ParseFail;
3146 SMLoc E = Parser.getTok().getLoc();
3147 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3148 unsigned Reg = Op.getGPR32Reg();
3149 Operands.pop_back();
3150 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3151 return MatchOperand_Success;
3154 MipsAsmParser::OperandMatchResultTy
3155 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3156 MCAsmParser &Parser = getParser();
3157 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3158 SmallVector<unsigned, 10> Regs;
3160 if (Parser.getTok().isNot(AsmToken::Dollar))
3161 return MatchOperand_ParseFail;
3163 SMLoc S = Parser.getTok().getLoc();
3165 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3166 return MatchOperand_ParseFail;
3168 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3169 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3170 Regs.push_back(RegNo);
3172 SMLoc E = Parser.getTok().getLoc();
3173 if (Parser.getTok().isNot(AsmToken::Comma)) {
3174 Error(E, "',' expected");
3175 return MatchOperand_ParseFail;
3181 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3182 return MatchOperand_ParseFail;
3184 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3185 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3186 Regs.push_back(RegNo);
3188 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3190 return MatchOperand_Success;
3193 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3195 MCSymbolRefExpr::VariantKind VK =
3196 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3197 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3198 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3199 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3200 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3201 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3202 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3203 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3204 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3205 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3206 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3207 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3208 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3209 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3210 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3211 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3212 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3213 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3214 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3215 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3216 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3217 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3218 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3219 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3220 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3221 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3222 .Default(MCSymbolRefExpr::VK_None);
3224 assert(VK != MCSymbolRefExpr::VK_None);
3229 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3231 /// ::= '(', register, ')'
3232 /// handle it before we iterate so we don't get tripped up by the lack of
3234 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3235 MCAsmParser &Parser = getParser();
3236 if (getLexer().is(AsmToken::LParen)) {
3238 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3240 if (parseOperand(Operands, Name)) {
3241 SMLoc Loc = getLexer().getLoc();
3242 Parser.eatToEndOfStatement();
3243 return Error(Loc, "unexpected token in argument list");
3245 if (Parser.getTok().isNot(AsmToken::RParen)) {
3246 SMLoc Loc = getLexer().getLoc();
3247 Parser.eatToEndOfStatement();
3248 return Error(Loc, "unexpected token, expected ')'");
3251 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3257 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3258 /// either one of these.
3259 /// ::= '[', register, ']'
3260 /// ::= '[', integer, ']'
3261 /// handle it before we iterate so we don't get tripped up by the lack of
3263 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3264 OperandVector &Operands) {
3265 MCAsmParser &Parser = getParser();
3266 if (getLexer().is(AsmToken::LBrac)) {
3268 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3270 if (parseOperand(Operands, Name)) {
3271 SMLoc Loc = getLexer().getLoc();
3272 Parser.eatToEndOfStatement();
3273 return Error(Loc, "unexpected token in argument list");
3275 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3276 SMLoc Loc = getLexer().getLoc();
3277 Parser.eatToEndOfStatement();
3278 return Error(Loc, "unexpected token, expected ']'");
3281 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3287 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3288 SMLoc NameLoc, OperandVector &Operands) {
3289 MCAsmParser &Parser = getParser();
3290 DEBUG(dbgs() << "ParseInstruction\n");
3292 // We have reached first instruction, module directive are now forbidden.
3293 getTargetStreamer().forbidModuleDirective();
3295 // Check if we have valid mnemonic
3296 if (!mnemonicIsValid(Name, 0)) {
3297 Parser.eatToEndOfStatement();
3298 return Error(NameLoc, "unknown instruction");
3300 // First operand in MCInst is instruction mnemonic.
3301 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3303 // Read the remaining operands.
3304 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3305 // Read the first operand.
3306 if (parseOperand(Operands, Name)) {
3307 SMLoc Loc = getLexer().getLoc();
3308 Parser.eatToEndOfStatement();
3309 return Error(Loc, "unexpected token in argument list");
3311 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3313 // AFAIK, parenthesis suffixes are never on the first operand
3315 while (getLexer().is(AsmToken::Comma)) {
3316 Parser.Lex(); // Eat the comma.
3317 // Parse and remember the operand.
3318 if (parseOperand(Operands, Name)) {
3319 SMLoc Loc = getLexer().getLoc();
3320 Parser.eatToEndOfStatement();
3321 return Error(Loc, "unexpected token in argument list");
3323 // Parse bracket and parenthesis suffixes before we iterate
3324 if (getLexer().is(AsmToken::LBrac)) {
3325 if (parseBracketSuffix(Name, Operands))
3327 } else if (getLexer().is(AsmToken::LParen) &&
3328 parseParenSuffix(Name, Operands))
3332 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3333 SMLoc Loc = getLexer().getLoc();
3334 Parser.eatToEndOfStatement();
3335 return Error(Loc, "unexpected token in argument list");
3337 Parser.Lex(); // Consume the EndOfStatement.
3341 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3342 MCAsmParser &Parser = getParser();
3343 SMLoc Loc = getLexer().getLoc();
3344 Parser.eatToEndOfStatement();
3345 return Error(Loc, ErrorMsg);
3348 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3349 return Error(Loc, ErrorMsg);
3352 bool MipsAsmParser::parseSetNoAtDirective() {
3353 MCAsmParser &Parser = getParser();
3354 // Line should look like: ".set noat".
3356 // Set the $at register to $0.
3357 AssemblerOptions.back()->setATRegIndex(0);
3359 Parser.Lex(); // Eat "noat".
3361 // If this is not the end of the statement, report an error.
3362 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3363 reportParseError("unexpected token, expected end of statement");
3367 getTargetStreamer().emitDirectiveSetNoAt();
3368 Parser.Lex(); // Consume the EndOfStatement.
3372 bool MipsAsmParser::parseSetAtDirective() {
3373 // Line can be: ".set at", which sets $at to $1
3374 // or ".set at=$reg", which sets $at to $reg.
3375 MCAsmParser &Parser = getParser();
3376 Parser.Lex(); // Eat "at".
3378 if (getLexer().is(AsmToken::EndOfStatement)) {
3379 // No register was specified, so we set $at to $1.
3380 AssemblerOptions.back()->setATRegIndex(1);
3382 getTargetStreamer().emitDirectiveSetAt();
3383 Parser.Lex(); // Consume the EndOfStatement.
3387 if (getLexer().isNot(AsmToken::Equal)) {
3388 reportParseError("unexpected token, expected equals sign");
3391 Parser.Lex(); // Eat "=".
3393 if (getLexer().isNot(AsmToken::Dollar)) {
3394 if (getLexer().is(AsmToken::EndOfStatement)) {
3395 reportParseError("no register specified");
3398 reportParseError("unexpected token, expected dollar sign '$'");
3402 Parser.Lex(); // Eat "$".
3404 // Find out what "reg" is.
3406 const AsmToken &Reg = Parser.getTok();
3407 if (Reg.is(AsmToken::Identifier)) {
3408 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3409 } else if (Reg.is(AsmToken::Integer)) {
3410 AtRegNo = Reg.getIntVal();
3412 reportParseError("unexpected token, expected identifier or integer");
3416 // Check if $reg is a valid register. If it is, set $at to $reg.
3417 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3418 reportParseError("invalid register");
3421 Parser.Lex(); // Eat "reg".
3423 // If this is not the end of the statement, report an error.
3424 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3425 reportParseError("unexpected token, expected end of statement");
3429 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3431 Parser.Lex(); // Consume the EndOfStatement.
3435 bool MipsAsmParser::parseSetReorderDirective() {
3436 MCAsmParser &Parser = getParser();
3438 // If this is not the end of the statement, report an error.
3439 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3440 reportParseError("unexpected token, expected end of statement");
3443 AssemblerOptions.back()->setReorder();
3444 getTargetStreamer().emitDirectiveSetReorder();
3445 Parser.Lex(); // Consume the EndOfStatement.
3449 bool MipsAsmParser::parseSetNoReorderDirective() {
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 AssemblerOptions.back()->setNoReorder();
3458 getTargetStreamer().emitDirectiveSetNoReorder();
3459 Parser.Lex(); // Consume the EndOfStatement.
3463 bool MipsAsmParser::parseSetMacroDirective() {
3464 MCAsmParser &Parser = getParser();
3466 // If this is not the end of the statement, report an error.
3467 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3468 reportParseError("unexpected token, expected end of statement");
3471 AssemblerOptions.back()->setMacro();
3472 getTargetStreamer().emitDirectiveSetMacro();
3473 Parser.Lex(); // Consume the EndOfStatement.
3477 bool MipsAsmParser::parseSetNoMacroDirective() {
3478 MCAsmParser &Parser = getParser();
3480 // If this is not the end of the statement, report an error.
3481 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3482 reportParseError("unexpected token, expected end of statement");
3485 if (AssemblerOptions.back()->isReorder()) {
3486 reportParseError("`noreorder' must be set before `nomacro'");
3489 AssemblerOptions.back()->setNoMacro();
3490 getTargetStreamer().emitDirectiveSetNoMacro();
3491 Parser.Lex(); // Consume the EndOfStatement.
3495 bool MipsAsmParser::parseSetMsaDirective() {
3496 MCAsmParser &Parser = getParser();
3499 // If this is not the end of the statement, report an error.
3500 if (getLexer().isNot(AsmToken::EndOfStatement))
3501 return reportParseError("unexpected token, expected end of statement");
3503 setFeatureBits(Mips::FeatureMSA, "msa");
3504 getTargetStreamer().emitDirectiveSetMsa();
3508 bool MipsAsmParser::parseSetNoMsaDirective() {
3509 MCAsmParser &Parser = getParser();
3512 // If this is not the end of the statement, report an error.
3513 if (getLexer().isNot(AsmToken::EndOfStatement))
3514 return reportParseError("unexpected token, expected end of statement");
3516 clearFeatureBits(Mips::FeatureMSA, "msa");
3517 getTargetStreamer().emitDirectiveSetNoMsa();
3521 bool MipsAsmParser::parseSetNoDspDirective() {
3522 MCAsmParser &Parser = getParser();
3523 Parser.Lex(); // Eat "nodsp".
3525 // If this is not the end of the statement, report an error.
3526 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3527 reportParseError("unexpected token, expected end of statement");
3531 clearFeatureBits(Mips::FeatureDSP, "dsp");
3532 getTargetStreamer().emitDirectiveSetNoDsp();
3536 bool MipsAsmParser::parseSetMips16Directive() {
3537 MCAsmParser &Parser = getParser();
3538 Parser.Lex(); // Eat "mips16".
3540 // If this is not the end of the statement, report an error.
3541 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3542 reportParseError("unexpected token, expected end of statement");
3546 setFeatureBits(Mips::FeatureMips16, "mips16");
3547 getTargetStreamer().emitDirectiveSetMips16();
3548 Parser.Lex(); // Consume the EndOfStatement.
3552 bool MipsAsmParser::parseSetNoMips16Directive() {
3553 MCAsmParser &Parser = getParser();
3554 Parser.Lex(); // Eat "nomips16".
3556 // If this is not the end of the statement, report an error.
3557 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3558 reportParseError("unexpected token, expected end of statement");
3562 clearFeatureBits(Mips::FeatureMips16, "mips16");
3563 getTargetStreamer().emitDirectiveSetNoMips16();
3564 Parser.Lex(); // Consume the EndOfStatement.
3568 bool MipsAsmParser::parseSetFpDirective() {
3569 MCAsmParser &Parser = getParser();
3570 MipsABIFlagsSection::FpABIKind FpAbiVal;
3571 // Line can be: .set fp=32
3574 Parser.Lex(); // Eat fp token
3575 AsmToken Tok = Parser.getTok();
3576 if (Tok.isNot(AsmToken::Equal)) {
3577 reportParseError("unexpected token, expected equals sign '='");
3580 Parser.Lex(); // Eat '=' token.
3581 Tok = Parser.getTok();
3583 if (!parseFpABIValue(FpAbiVal, ".set"))
3586 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3587 reportParseError("unexpected token, expected end of statement");
3590 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3591 Parser.Lex(); // Consume the EndOfStatement.
3595 bool MipsAsmParser::parseSetPopDirective() {
3596 MCAsmParser &Parser = getParser();
3597 SMLoc Loc = getLexer().getLoc();
3600 if (getLexer().isNot(AsmToken::EndOfStatement))
3601 return reportParseError("unexpected token, expected end of statement");
3603 // Always keep an element on the options "stack" to prevent the user
3604 // from changing the initial options. This is how we remember them.
3605 if (AssemblerOptions.size() == 2)
3606 return reportParseError(Loc, ".set pop with no .set push");
3608 AssemblerOptions.pop_back();
3609 setAvailableFeatures(
3610 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
3611 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
3613 getTargetStreamer().emitDirectiveSetPop();
3617 bool MipsAsmParser::parseSetPushDirective() {
3618 MCAsmParser &Parser = getParser();
3620 if (getLexer().isNot(AsmToken::EndOfStatement))
3621 return reportParseError("unexpected token, expected end of statement");
3623 // Create a copy of the current assembler options environment and push it.
3624 AssemblerOptions.push_back(
3625 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3627 getTargetStreamer().emitDirectiveSetPush();
3631 bool MipsAsmParser::parseSetSoftFloatDirective() {
3632 MCAsmParser &Parser = getParser();
3634 if (getLexer().isNot(AsmToken::EndOfStatement))
3635 return reportParseError("unexpected token, expected end of statement");
3637 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3638 getTargetStreamer().emitDirectiveSetSoftFloat();
3642 bool MipsAsmParser::parseSetHardFloatDirective() {
3643 MCAsmParser &Parser = getParser();
3645 if (getLexer().isNot(AsmToken::EndOfStatement))
3646 return reportParseError("unexpected token, expected end of statement");
3648 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3649 getTargetStreamer().emitDirectiveSetHardFloat();
3653 bool MipsAsmParser::parseSetAssignment() {
3655 const MCExpr *Value;
3656 MCAsmParser &Parser = getParser();
3658 if (Parser.parseIdentifier(Name))
3659 reportParseError("expected identifier after .set");
3661 if (getLexer().isNot(AsmToken::Comma))
3662 return reportParseError("unexpected token, expected comma");
3665 if (Parser.parseExpression(Value))
3666 return reportParseError("expected valid expression after comma");
3668 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3669 Sym->setVariableValue(Value);
3674 bool MipsAsmParser::parseSetMips0Directive() {
3675 MCAsmParser &Parser = getParser();
3677 if (getLexer().isNot(AsmToken::EndOfStatement))
3678 return reportParseError("unexpected token, expected end of statement");
3680 // Reset assembler options to their initial values.
3681 setAvailableFeatures(
3682 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
3683 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
3684 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3686 getTargetStreamer().emitDirectiveSetMips0();
3690 bool MipsAsmParser::parseSetArchDirective() {
3691 MCAsmParser &Parser = getParser();
3693 if (getLexer().isNot(AsmToken::Equal))
3694 return reportParseError("unexpected token, expected equals sign");
3698 if (Parser.parseIdentifier(Arch))
3699 return reportParseError("expected arch identifier");
3701 StringRef ArchFeatureName =
3702 StringSwitch<StringRef>(Arch)
3703 .Case("mips1", "mips1")
3704 .Case("mips2", "mips2")
3705 .Case("mips3", "mips3")
3706 .Case("mips4", "mips4")
3707 .Case("mips5", "mips5")
3708 .Case("mips32", "mips32")
3709 .Case("mips32r2", "mips32r2")
3710 .Case("mips32r3", "mips32r3")
3711 .Case("mips32r5", "mips32r5")
3712 .Case("mips32r6", "mips32r6")
3713 .Case("mips64", "mips64")
3714 .Case("mips64r2", "mips64r2")
3715 .Case("mips64r3", "mips64r3")
3716 .Case("mips64r5", "mips64r5")
3717 .Case("mips64r6", "mips64r6")
3718 .Case("cnmips", "cnmips")
3719 .Case("r4000", "mips3") // This is an implementation of Mips3.
3722 if (ArchFeatureName.empty())
3723 return reportParseError("unsupported architecture");
3725 selectArch(ArchFeatureName);
3726 getTargetStreamer().emitDirectiveSetArch(Arch);
3730 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3731 MCAsmParser &Parser = getParser();
3733 if (getLexer().isNot(AsmToken::EndOfStatement))
3734 return reportParseError("unexpected token, expected end of statement");
3738 llvm_unreachable("Unimplemented feature");
3739 case Mips::FeatureDSP:
3740 setFeatureBits(Mips::FeatureDSP, "dsp");
3741 getTargetStreamer().emitDirectiveSetDsp();
3743 case Mips::FeatureMicroMips:
3744 getTargetStreamer().emitDirectiveSetMicroMips();
3746 case Mips::FeatureMips1:
3747 selectArch("mips1");
3748 getTargetStreamer().emitDirectiveSetMips1();
3750 case Mips::FeatureMips2:
3751 selectArch("mips2");
3752 getTargetStreamer().emitDirectiveSetMips2();
3754 case Mips::FeatureMips3:
3755 selectArch("mips3");
3756 getTargetStreamer().emitDirectiveSetMips3();
3758 case Mips::FeatureMips4:
3759 selectArch("mips4");
3760 getTargetStreamer().emitDirectiveSetMips4();
3762 case Mips::FeatureMips5:
3763 selectArch("mips5");
3764 getTargetStreamer().emitDirectiveSetMips5();
3766 case Mips::FeatureMips32:
3767 selectArch("mips32");
3768 getTargetStreamer().emitDirectiveSetMips32();
3770 case Mips::FeatureMips32r2:
3771 selectArch("mips32r2");
3772 getTargetStreamer().emitDirectiveSetMips32R2();
3774 case Mips::FeatureMips32r3:
3775 selectArch("mips32r3");
3776 getTargetStreamer().emitDirectiveSetMips32R3();
3778 case Mips::FeatureMips32r5:
3779 selectArch("mips32r5");
3780 getTargetStreamer().emitDirectiveSetMips32R5();
3782 case Mips::FeatureMips32r6:
3783 selectArch("mips32r6");
3784 getTargetStreamer().emitDirectiveSetMips32R6();
3786 case Mips::FeatureMips64:
3787 selectArch("mips64");
3788 getTargetStreamer().emitDirectiveSetMips64();
3790 case Mips::FeatureMips64r2:
3791 selectArch("mips64r2");
3792 getTargetStreamer().emitDirectiveSetMips64R2();
3794 case Mips::FeatureMips64r3:
3795 selectArch("mips64r3");
3796 getTargetStreamer().emitDirectiveSetMips64R3();
3798 case Mips::FeatureMips64r5:
3799 selectArch("mips64r5");
3800 getTargetStreamer().emitDirectiveSetMips64R5();
3802 case Mips::FeatureMips64r6:
3803 selectArch("mips64r6");
3804 getTargetStreamer().emitDirectiveSetMips64R6();
3810 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3811 MCAsmParser &Parser = getParser();
3812 if (getLexer().isNot(AsmToken::Comma)) {
3813 SMLoc Loc = getLexer().getLoc();
3814 Parser.eatToEndOfStatement();
3815 return Error(Loc, ErrorStr);
3818 Parser.Lex(); // Eat the comma.
3822 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3823 if (AssemblerOptions.back()->isReorder())
3824 Warning(Loc, ".cpload should be inside a noreorder section");
3826 if (inMips16Mode()) {
3827 reportParseError(".cpload is not supported in Mips16 mode");
3831 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3832 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3833 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3834 reportParseError("expected register containing function address");
3838 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3839 if (!RegOpnd.isGPRAsmReg()) {
3840 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3844 // If this is not the end of the statement, report an error.
3845 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3846 reportParseError("unexpected token, expected end of statement");
3850 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3854 bool MipsAsmParser::parseDirectiveCPSetup() {
3855 MCAsmParser &Parser = getParser();
3858 bool SaveIsReg = true;
3860 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3861 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3862 if (ResTy == MatchOperand_NoMatch) {
3863 reportParseError("expected register containing function address");
3864 Parser.eatToEndOfStatement();
3868 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3869 if (!FuncRegOpnd.isGPRAsmReg()) {
3870 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3871 Parser.eatToEndOfStatement();
3875 FuncReg = FuncRegOpnd.getGPR32Reg();
3878 if (!eatComma("unexpected token, expected comma"))
3881 ResTy = parseAnyRegister(TmpReg);
3882 if (ResTy == MatchOperand_NoMatch) {
3883 const AsmToken &Tok = Parser.getTok();
3884 if (Tok.is(AsmToken::Integer)) {
3885 Save = Tok.getIntVal();
3889 reportParseError("expected save register or stack offset");
3890 Parser.eatToEndOfStatement();
3894 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3895 if (!SaveOpnd.isGPRAsmReg()) {
3896 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3897 Parser.eatToEndOfStatement();
3900 Save = SaveOpnd.getGPR32Reg();
3903 if (!eatComma("unexpected token, expected comma"))
3907 if (Parser.parseExpression(Expr)) {
3908 reportParseError("expected expression");
3912 if (Expr->getKind() != MCExpr::SymbolRef) {
3913 reportParseError("expected symbol");
3916 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3918 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3923 bool MipsAsmParser::parseDirectiveNaN() {
3924 MCAsmParser &Parser = getParser();
3925 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3926 const AsmToken &Tok = Parser.getTok();
3928 if (Tok.getString() == "2008") {
3930 getTargetStreamer().emitDirectiveNaN2008();
3932 } else if (Tok.getString() == "legacy") {
3934 getTargetStreamer().emitDirectiveNaNLegacy();
3938 // If we don't recognize the option passed to the .nan
3939 // directive (e.g. no option or unknown option), emit an error.
3940 reportParseError("invalid option in .nan directive");
3944 bool MipsAsmParser::parseDirectiveSet() {
3945 MCAsmParser &Parser = getParser();
3946 // Get the next token.
3947 const AsmToken &Tok = Parser.getTok();
3949 if (Tok.getString() == "noat") {
3950 return parseSetNoAtDirective();
3951 } else if (Tok.getString() == "at") {
3952 return parseSetAtDirective();
3953 } else if (Tok.getString() == "arch") {
3954 return parseSetArchDirective();
3955 } else if (Tok.getString() == "fp") {
3956 return parseSetFpDirective();
3957 } else if (Tok.getString() == "pop") {
3958 return parseSetPopDirective();
3959 } else if (Tok.getString() == "push") {
3960 return parseSetPushDirective();
3961 } else if (Tok.getString() == "reorder") {
3962 return parseSetReorderDirective();
3963 } else if (Tok.getString() == "noreorder") {
3964 return parseSetNoReorderDirective();
3965 } else if (Tok.getString() == "macro") {
3966 return parseSetMacroDirective();
3967 } else if (Tok.getString() == "nomacro") {
3968 return parseSetNoMacroDirective();
3969 } else if (Tok.getString() == "mips16") {
3970 return parseSetMips16Directive();
3971 } else if (Tok.getString() == "nomips16") {
3972 return parseSetNoMips16Directive();
3973 } else if (Tok.getString() == "nomicromips") {
3974 getTargetStreamer().emitDirectiveSetNoMicroMips();
3975 Parser.eatToEndOfStatement();
3977 } else if (Tok.getString() == "micromips") {
3978 return parseSetFeature(Mips::FeatureMicroMips);
3979 } else if (Tok.getString() == "mips0") {
3980 return parseSetMips0Directive();
3981 } else if (Tok.getString() == "mips1") {
3982 return parseSetFeature(Mips::FeatureMips1);
3983 } else if (Tok.getString() == "mips2") {
3984 return parseSetFeature(Mips::FeatureMips2);
3985 } else if (Tok.getString() == "mips3") {
3986 return parseSetFeature(Mips::FeatureMips3);
3987 } else if (Tok.getString() == "mips4") {
3988 return parseSetFeature(Mips::FeatureMips4);
3989 } else if (Tok.getString() == "mips5") {
3990 return parseSetFeature(Mips::FeatureMips5);
3991 } else if (Tok.getString() == "mips32") {
3992 return parseSetFeature(Mips::FeatureMips32);
3993 } else if (Tok.getString() == "mips32r2") {
3994 return parseSetFeature(Mips::FeatureMips32r2);
3995 } else if (Tok.getString() == "mips32r3") {
3996 return parseSetFeature(Mips::FeatureMips32r3);
3997 } else if (Tok.getString() == "mips32r5") {
3998 return parseSetFeature(Mips::FeatureMips32r5);
3999 } else if (Tok.getString() == "mips32r6") {
4000 return parseSetFeature(Mips::FeatureMips32r6);
4001 } else if (Tok.getString() == "mips64") {
4002 return parseSetFeature(Mips::FeatureMips64);
4003 } else if (Tok.getString() == "mips64r2") {
4004 return parseSetFeature(Mips::FeatureMips64r2);
4005 } else if (Tok.getString() == "mips64r3") {
4006 return parseSetFeature(Mips::FeatureMips64r3);
4007 } else if (Tok.getString() == "mips64r5") {
4008 return parseSetFeature(Mips::FeatureMips64r5);
4009 } else if (Tok.getString() == "mips64r6") {
4010 return parseSetFeature(Mips::FeatureMips64r6);
4011 } else if (Tok.getString() == "dsp") {
4012 return parseSetFeature(Mips::FeatureDSP);
4013 } else if (Tok.getString() == "nodsp") {
4014 return parseSetNoDspDirective();
4015 } else if (Tok.getString() == "msa") {
4016 return parseSetMsaDirective();
4017 } else if (Tok.getString() == "nomsa") {
4018 return parseSetNoMsaDirective();
4019 } else if (Tok.getString() == "softfloat") {
4020 return parseSetSoftFloatDirective();
4021 } else if (Tok.getString() == "hardfloat") {
4022 return parseSetHardFloatDirective();
4024 // It is just an identifier, look for an assignment.
4025 parseSetAssignment();
4032 /// parseDataDirective
4033 /// ::= .word [ expression (, expression)* ]
4034 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4035 MCAsmParser &Parser = getParser();
4036 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4038 const MCExpr *Value;
4039 if (getParser().parseExpression(Value))
4042 getParser().getStreamer().EmitValue(Value, Size);
4044 if (getLexer().is(AsmToken::EndOfStatement))
4047 if (getLexer().isNot(AsmToken::Comma))
4048 return Error(L, "unexpected token, expected comma");
4057 /// parseDirectiveGpWord
4058 /// ::= .gpword local_sym
4059 bool MipsAsmParser::parseDirectiveGpWord() {
4060 MCAsmParser &Parser = getParser();
4061 const MCExpr *Value;
4062 // EmitGPRel32Value requires an expression, so we are using base class
4063 // method to evaluate the expression.
4064 if (getParser().parseExpression(Value))
4066 getParser().getStreamer().EmitGPRel32Value(Value);
4068 if (getLexer().isNot(AsmToken::EndOfStatement))
4069 return Error(getLexer().getLoc(),
4070 "unexpected token, expected end of statement");
4071 Parser.Lex(); // Eat EndOfStatement token.
4075 /// parseDirectiveGpDWord
4076 /// ::= .gpdword local_sym
4077 bool MipsAsmParser::parseDirectiveGpDWord() {
4078 MCAsmParser &Parser = getParser();
4079 const MCExpr *Value;
4080 // EmitGPRel64Value requires an expression, so we are using base class
4081 // method to evaluate the expression.
4082 if (getParser().parseExpression(Value))
4084 getParser().getStreamer().EmitGPRel64Value(Value);
4086 if (getLexer().isNot(AsmToken::EndOfStatement))
4087 return Error(getLexer().getLoc(),
4088 "unexpected token, expected end of statement");
4089 Parser.Lex(); // Eat EndOfStatement token.
4093 bool MipsAsmParser::parseDirectiveOption() {
4094 MCAsmParser &Parser = getParser();
4095 // Get the option token.
4096 AsmToken Tok = Parser.getTok();
4097 // At the moment only identifiers are supported.
4098 if (Tok.isNot(AsmToken::Identifier)) {
4099 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4100 Parser.eatToEndOfStatement();
4104 StringRef Option = Tok.getIdentifier();
4106 if (Option == "pic0") {
4107 getTargetStreamer().emitDirectiveOptionPic0();
4109 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4110 Error(Parser.getTok().getLoc(),
4111 "unexpected token, expected end of statement");
4112 Parser.eatToEndOfStatement();
4117 if (Option == "pic2") {
4118 getTargetStreamer().emitDirectiveOptionPic2();
4120 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4121 Error(Parser.getTok().getLoc(),
4122 "unexpected token, expected end of statement");
4123 Parser.eatToEndOfStatement();
4129 Warning(Parser.getTok().getLoc(),
4130 "unknown option, expected 'pic0' or 'pic2'");
4131 Parser.eatToEndOfStatement();
4135 /// parseInsnDirective
4137 bool MipsAsmParser::parseInsnDirective() {
4138 // If this is not the end of the statement, report an error.
4139 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4140 reportParseError("unexpected token, expected end of statement");
4144 // The actual label marking happens in
4145 // MipsELFStreamer::createPendingLabelRelocs().
4146 getTargetStreamer().emitDirectiveInsn();
4148 getParser().Lex(); // Eat EndOfStatement token.
4152 /// parseDirectiveModule
4153 /// ::= .module oddspreg
4154 /// ::= .module nooddspreg
4155 /// ::= .module fp=value
4156 bool MipsAsmParser::parseDirectiveModule() {
4157 MCAsmParser &Parser = getParser();
4158 MCAsmLexer &Lexer = getLexer();
4159 SMLoc L = Lexer.getLoc();
4161 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4162 // TODO : get a better message.
4163 reportParseError(".module directive must appear before any code");
4168 if (Parser.parseIdentifier(Option)) {
4169 reportParseError("expected .module option identifier");
4173 if (Option == "oddspreg") {
4174 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4175 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4177 // If this is not the end of the statement, report an error.
4178 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4179 reportParseError("unexpected token, expected end of statement");
4183 return false; // parseDirectiveModule has finished successfully.
4184 } else if (Option == "nooddspreg") {
4186 Error(L, "'.module nooddspreg' requires the O32 ABI");
4190 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4191 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4193 // If this is not the end of the statement, report an error.
4194 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4195 reportParseError("unexpected token, expected end of statement");
4199 return false; // parseDirectiveModule has finished successfully.
4200 } else if (Option == "fp") {
4201 return parseDirectiveModuleFP();
4203 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4207 /// parseDirectiveModuleFP
4211 bool MipsAsmParser::parseDirectiveModuleFP() {
4212 MCAsmParser &Parser = getParser();
4213 MCAsmLexer &Lexer = getLexer();
4215 if (Lexer.isNot(AsmToken::Equal)) {
4216 reportParseError("unexpected token, expected equals sign '='");
4219 Parser.Lex(); // Eat '=' token.
4221 MipsABIFlagsSection::FpABIKind FpABI;
4222 if (!parseFpABIValue(FpABI, ".module"))
4225 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4226 reportParseError("unexpected token, expected end of statement");
4230 // Emit appropriate flags.
4231 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4232 Parser.Lex(); // Consume the EndOfStatement.
4236 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4237 StringRef Directive) {
4238 MCAsmParser &Parser = getParser();
4239 MCAsmLexer &Lexer = getLexer();
4241 if (Lexer.is(AsmToken::Identifier)) {
4242 StringRef Value = Parser.getTok().getString();
4245 if (Value != "xx") {
4246 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4251 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4255 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4259 if (Lexer.is(AsmToken::Integer)) {
4260 unsigned Value = Parser.getTok().getIntVal();
4263 if (Value != 32 && Value != 64) {
4264 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4270 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4274 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4276 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4284 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4285 MCAsmParser &Parser = getParser();
4286 StringRef IDVal = DirectiveID.getString();
4288 if (IDVal == ".cpload")
4289 return parseDirectiveCpLoad(DirectiveID.getLoc());
4290 if (IDVal == ".dword") {
4291 parseDataDirective(8, DirectiveID.getLoc());
4294 if (IDVal == ".ent") {
4295 StringRef SymbolName;
4297 if (Parser.parseIdentifier(SymbolName)) {
4298 reportParseError("expected identifier after .ent");
4302 // There's an undocumented extension that allows an integer to
4303 // follow the name of the procedure which AFAICS is ignored by GAS.
4304 // Example: .ent foo,2
4305 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4306 if (getLexer().isNot(AsmToken::Comma)) {
4307 // Even though we accept this undocumented extension for compatibility
4308 // reasons, the additional integer argument does not actually change
4309 // the behaviour of the '.ent' directive, so we would like to discourage
4310 // its use. We do this by not referring to the extended version in
4311 // error messages which are not directly related to its use.
4312 reportParseError("unexpected token, expected end of statement");
4315 Parser.Lex(); // Eat the comma.
4316 const MCExpr *DummyNumber;
4317 int64_t DummyNumberVal;
4318 // If the user was explicitly trying to use the extended version,
4319 // we still give helpful extension-related error messages.
4320 if (Parser.parseExpression(DummyNumber)) {
4321 reportParseError("expected number after comma");
4324 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4325 reportParseError("expected an absolute expression after comma");
4330 // If this is not the end of the statement, report an error.
4331 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4332 reportParseError("unexpected token, expected end of statement");
4336 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4338 getTargetStreamer().emitDirectiveEnt(*Sym);
4343 if (IDVal == ".end") {
4344 StringRef SymbolName;
4346 if (Parser.parseIdentifier(SymbolName)) {
4347 reportParseError("expected identifier after .end");
4351 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4352 reportParseError("unexpected token, expected end of statement");
4356 if (CurrentFn == nullptr) {
4357 reportParseError(".end used without .ent");
4361 if ((SymbolName != CurrentFn->getName())) {
4362 reportParseError(".end symbol does not match .ent symbol");
4366 getTargetStreamer().emitDirectiveEnd(SymbolName);
4367 CurrentFn = nullptr;
4371 if (IDVal == ".frame") {
4372 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4373 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4374 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4375 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4376 reportParseError("expected stack register");
4380 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4381 if (!StackRegOpnd.isGPRAsmReg()) {
4382 reportParseError(StackRegOpnd.getStartLoc(),
4383 "expected general purpose register");
4386 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4388 if (Parser.getTok().is(AsmToken::Comma))
4391 reportParseError("unexpected token, expected comma");
4395 // Parse the frame size.
4396 const MCExpr *FrameSize;
4397 int64_t FrameSizeVal;
4399 if (Parser.parseExpression(FrameSize)) {
4400 reportParseError("expected frame size value");
4404 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4405 reportParseError("frame size not an absolute expression");
4409 if (Parser.getTok().is(AsmToken::Comma))
4412 reportParseError("unexpected token, expected comma");
4416 // Parse the return register.
4418 ResTy = parseAnyRegister(TmpReg);
4419 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4420 reportParseError("expected return register");
4424 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4425 if (!ReturnRegOpnd.isGPRAsmReg()) {
4426 reportParseError(ReturnRegOpnd.getStartLoc(),
4427 "expected general purpose register");
4431 // If this is not the end of the statement, report an error.
4432 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4433 reportParseError("unexpected token, expected end of statement");
4437 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4438 ReturnRegOpnd.getGPR32Reg());
4442 if (IDVal == ".set") {
4443 return parseDirectiveSet();
4446 if (IDVal == ".mask" || IDVal == ".fmask") {
4447 // .mask bitmask, frame_offset
4448 // bitmask: One bit for each register used.
4449 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4450 // first register is expected to be saved.
4452 // .mask 0x80000000, -4
4453 // .fmask 0x80000000, -4
4456 // Parse the bitmask
4457 const MCExpr *BitMask;
4460 if (Parser.parseExpression(BitMask)) {
4461 reportParseError("expected bitmask value");
4465 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4466 reportParseError("bitmask not an absolute expression");
4470 if (Parser.getTok().is(AsmToken::Comma))
4473 reportParseError("unexpected token, expected comma");
4477 // Parse the frame_offset
4478 const MCExpr *FrameOffset;
4479 int64_t FrameOffsetVal;
4481 if (Parser.parseExpression(FrameOffset)) {
4482 reportParseError("expected frame offset value");
4486 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4487 reportParseError("frame offset not an absolute expression");
4491 // If this is not the end of the statement, report an error.
4492 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4493 reportParseError("unexpected token, expected end of statement");
4497 if (IDVal == ".mask")
4498 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4500 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4504 if (IDVal == ".nan")
4505 return parseDirectiveNaN();
4507 if (IDVal == ".gpword") {
4508 parseDirectiveGpWord();
4512 if (IDVal == ".gpdword") {
4513 parseDirectiveGpDWord();
4517 if (IDVal == ".word") {
4518 parseDataDirective(4, DirectiveID.getLoc());
4522 if (IDVal == ".option")
4523 return parseDirectiveOption();
4525 if (IDVal == ".abicalls") {
4526 getTargetStreamer().emitDirectiveAbiCalls();
4527 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4528 Error(Parser.getTok().getLoc(),
4529 "unexpected token, expected end of statement");
4531 Parser.eatToEndOfStatement();
4536 if (IDVal == ".cpsetup")
4537 return parseDirectiveCPSetup();
4539 if (IDVal == ".module")
4540 return parseDirectiveModule();
4542 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4543 return parseInternalDirectiveReallowModule();
4545 if (IDVal == ".insn")
4546 return parseInsnDirective();
4551 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4552 // If this is not the end of the statement, report an error.
4553 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4554 reportParseError("unexpected token, expected end of statement");
4558 getTargetStreamer().reallowModuleDirective();
4560 getParser().Lex(); // Eat EndOfStatement token.
4564 extern "C" void LLVMInitializeMipsAsmParser() {
4565 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4566 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4567 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4568 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4571 #define GET_REGISTER_MATCHER
4572 #define GET_MATCHER_IMPLEMENTATION
4573 #include "MipsGenAsmMatcher.inc"