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 "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCParser/MCAsmLexer.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCTargetAsmParser.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
38 #define DEBUG_TYPE "mips-asm-parser"
45 class MipsAssemblerOptions {
47 MipsAssemblerOptions(const FeatureBitset &Features_) :
48 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
50 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
51 ATReg = Opts->getATRegIndex();
52 Reorder = Opts->isReorder();
53 Macro = Opts->isMacro();
54 Features = Opts->getFeatures();
57 unsigned getATRegIndex() const { return ATReg; }
58 bool setATRegIndex(unsigned Reg) {
66 bool isReorder() const { return Reorder; }
67 void setReorder() { Reorder = true; }
68 void setNoReorder() { Reorder = false; }
70 bool isMacro() const { return Macro; }
71 void setMacro() { Macro = true; }
72 void setNoMacro() { Macro = false; }
74 const FeatureBitset &getFeatures() const { return Features; }
75 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
77 // Set of features that are either architecture features or referenced
78 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
79 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
80 // The reason we need this mask is explained in the selectArch function.
81 // FIXME: Ideally we would like TableGen to generate this information.
82 static const FeatureBitset AllArchRelatedMask;
88 FeatureBitset Features;
92 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
93 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
94 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
95 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
96 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
97 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
98 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
99 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
100 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
104 class MipsAsmParser : public MCTargetAsmParser {
105 MipsTargetStreamer &getTargetStreamer() {
106 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
107 return static_cast<MipsTargetStreamer &>(TS);
110 MCSubtargetInfo &STI;
112 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
113 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
114 // nullptr, which indicates that no function is currently
115 // selected. This usually happens after an '.end func'
121 unsigned CpSaveLocation;
122 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
123 bool CpSaveLocationIsRegister;
125 // Print a warning along with its fix-it message at the given range.
126 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
127 SMRange Range, bool ShowColors = true);
129 #define GET_ASSEMBLER_HEADER
130 #include "MipsGenAsmMatcher.inc"
132 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
134 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
135 OperandVector &Operands, MCStreamer &Out,
137 bool MatchingInlineAsm) override;
139 /// Parse a register as used in CFI directives
140 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
142 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
144 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
146 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
147 SMLoc NameLoc, OperandVector &Operands) override;
149 bool ParseDirective(AsmToken DirectiveID) override;
151 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
153 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
154 StringRef Identifier, SMLoc S);
155 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
157 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
158 OperandMatchResultTy parseImm(OperandVector &Operands);
159 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
160 OperandMatchResultTy parseInvNum(OperandVector &Operands);
161 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
163 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
164 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
166 bool searchSymbolAlias(OperandVector &Operands);
168 bool parseOperand(OperandVector &, StringRef Mnemonic);
170 bool needsExpansion(MCInst &Inst);
172 // Expands assembly pseudo instructions.
173 // Returns false on success, true otherwise.
174 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
175 SmallVectorImpl<MCInst> &Instructions);
177 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
178 SmallVectorImpl<MCInst> &Instructions);
180 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
181 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
182 SmallVectorImpl<MCInst> &Instructions);
184 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
185 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
191 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
192 const MCOperand &Offset, bool Is32BitAddress,
193 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
195 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions);
198 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
199 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
202 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions);
205 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions);
208 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
215 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
218 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions);
221 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
222 SmallVectorImpl<MCInst> &Instructions);
224 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
225 SmallVectorImpl<MCInst> &Instructions);
227 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
228 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
230 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
231 SmallVectorImpl<MCInst> &Instructions);
233 bool reportParseError(Twine ErrorMsg);
234 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
236 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
237 bool parseRelocOperand(const MCExpr *&Res);
239 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
241 bool isEvaluated(const MCExpr *Expr);
242 bool parseSetMips0Directive();
243 bool parseSetArchDirective();
244 bool parseSetFeature(uint64_t Feature);
245 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
246 bool parseDirectiveCpLoad(SMLoc Loc);
247 bool parseDirectiveCpRestore(SMLoc Loc);
248 bool parseDirectiveCPSetup();
249 bool parseDirectiveCPReturn();
250 bool parseDirectiveNaN();
251 bool parseDirectiveSet();
252 bool parseDirectiveOption();
253 bool parseInsnDirective();
255 bool parseSetAtDirective();
256 bool parseSetNoAtDirective();
257 bool parseSetMacroDirective();
258 bool parseSetNoMacroDirective();
259 bool parseSetMsaDirective();
260 bool parseSetNoMsaDirective();
261 bool parseSetNoDspDirective();
262 bool parseSetReorderDirective();
263 bool parseSetNoReorderDirective();
264 bool parseSetMips16Directive();
265 bool parseSetNoMips16Directive();
266 bool parseSetFpDirective();
267 bool parseSetOddSPRegDirective();
268 bool parseSetNoOddSPRegDirective();
269 bool parseSetPopDirective();
270 bool parseSetPushDirective();
271 bool parseSetSoftFloatDirective();
272 bool parseSetHardFloatDirective();
274 bool parseSetAssignment();
276 bool parseDataDirective(unsigned Size, SMLoc L);
277 bool parseDirectiveGpWord();
278 bool parseDirectiveGpDWord();
279 bool parseDirectiveModule();
280 bool parseDirectiveModuleFP();
281 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
282 StringRef Directive);
284 bool parseInternalDirectiveReallowModule();
286 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
288 bool eatComma(StringRef ErrorStr);
290 int matchCPURegisterName(StringRef Symbol);
292 int matchHWRegsRegisterName(StringRef Symbol);
294 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
296 int matchFPURegisterName(StringRef Name);
298 int matchFCCRegisterName(StringRef Name);
300 int matchACRegisterName(StringRef Name);
302 int matchMSA128RegisterName(StringRef Name);
304 int matchMSA128CtrlRegisterName(StringRef Name);
306 unsigned getReg(int RC, int RegNo);
308 unsigned getGPR(int RegNo);
310 /// Returns the internal register number for the current AT. Also checks if
311 /// the current AT is unavailable (set to $0) and gives an error if it is.
312 /// This should be used in pseudo-instruction expansions which need AT.
313 unsigned getATReg(SMLoc Loc);
315 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
316 SmallVectorImpl<MCInst> &Instructions);
318 // Helper function that checks if the value of a vector index is within the
319 // boundaries of accepted values for each RegisterKind
320 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
321 bool validateMSAIndex(int Val, int RegKind);
323 // Selects a new architecture by updating the FeatureBits with the necessary
324 // info including implied dependencies.
325 // Internally, it clears all the feature bits related to *any* architecture
326 // and selects the new one using the ToggleFeature functionality of the
327 // MCSubtargetInfo object that handles implied dependencies. The reason we
328 // clear all the arch related bits manually is because ToggleFeature only
329 // clears the features that imply the feature being cleared and not the
330 // features implied by the feature being cleared. This is easier to see
332 // --------------------------------------------------
333 // | Feature | Implies |
334 // | -------------------------------------------------|
335 // | FeatureMips1 | None |
336 // | FeatureMips2 | FeatureMips1 |
337 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
338 // | FeatureMips4 | FeatureMips3 |
340 // --------------------------------------------------
342 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
343 // FeatureMipsGP64 | FeatureMips1)
344 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
345 void selectArch(StringRef ArchFeature) {
346 FeatureBitset FeatureBits = STI.getFeatureBits();
347 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
348 STI.setFeatureBits(FeatureBits);
349 setAvailableFeatures(
350 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
351 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
354 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
355 if (!(STI.getFeatureBits()[Feature])) {
356 setAvailableFeatures(
357 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
358 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
362 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
363 if (STI.getFeatureBits()[Feature]) {
364 setAvailableFeatures(
365 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
366 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
370 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
371 setFeatureBits(Feature, FeatureString);
372 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
375 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
376 clearFeatureBits(Feature, FeatureString);
377 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
381 enum MipsMatchResultTy {
382 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
383 #define GET_OPERAND_DIAGNOSTIC_TYPES
384 #include "MipsGenAsmMatcher.inc"
385 #undef GET_OPERAND_DIAGNOSTIC_TYPES
389 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
390 const MCInstrInfo &MII, const MCTargetOptions &Options)
391 : MCTargetAsmParser(Options), STI(sti),
392 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
393 sti.getCPU(), Options)) {
394 MCAsmParserExtension::Initialize(parser);
396 parser.addAliasForDirective(".asciiz", ".asciz");
398 // Initialize the set of available features.
399 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
401 // Remember the initial assembler options. The user can not modify these.
402 AssemblerOptions.push_back(
403 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
405 // Create an assembler options environment for the user to modify.
406 AssemblerOptions.push_back(
407 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
409 getTargetStreamer().updateABIInfo(*this);
411 if (!isABI_O32() && !useOddSPReg() != 0)
412 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
417 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
419 IsCpRestoreSet = false;
420 CpRestoreOffset = -1;
422 Triple TheTriple(sti.getTargetTriple());
423 if ((TheTriple.getArch() == Triple::mips) ||
424 (TheTriple.getArch() == Triple::mips64))
425 IsLittleEndian = false;
427 IsLittleEndian = true;
430 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
431 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
433 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
434 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
435 const MipsABIInfo &getABI() const { return ABI; }
436 bool isABI_N32() const { return ABI.IsN32(); }
437 bool isABI_N64() const { return ABI.IsN64(); }
438 bool isABI_O32() const { return ABI.IsO32(); }
439 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
441 bool useOddSPReg() const {
442 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
445 bool inMicroMipsMode() const {
446 return STI.getFeatureBits()[Mips::FeatureMicroMips];
448 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
449 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
450 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
451 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
452 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
453 bool hasMips32() const {
454 return STI.getFeatureBits()[Mips::FeatureMips32];
456 bool hasMips64() const {
457 return STI.getFeatureBits()[Mips::FeatureMips64];
459 bool hasMips32r2() const {
460 return STI.getFeatureBits()[Mips::FeatureMips32r2];
462 bool hasMips64r2() const {
463 return STI.getFeatureBits()[Mips::FeatureMips64r2];
465 bool hasMips32r3() const {
466 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
468 bool hasMips64r3() const {
469 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
471 bool hasMips32r5() const {
472 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
474 bool hasMips64r5() const {
475 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
477 bool hasMips32r6() const {
478 return STI.getFeatureBits()[Mips::FeatureMips32r6];
480 bool hasMips64r6() const {
481 return STI.getFeatureBits()[Mips::FeatureMips64r6];
484 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
485 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
486 bool hasDSPR3() const { return STI.getFeatureBits()[Mips::FeatureDSPR3]; }
487 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
488 bool hasCnMips() const {
489 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
496 bool inMips16Mode() const {
497 return STI.getFeatureBits()[Mips::FeatureMips16];
500 bool useTraps() const {
501 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
504 bool useSoftFloat() const {
505 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
508 /// Warn if RegIndex is the same as the current AT.
509 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
511 void warnIfNoMacro(SMLoc Loc);
513 bool isLittle() const { return IsLittleEndian; }
519 /// MipsOperand - Instances of this class represent a parsed Mips machine
521 class MipsOperand : public MCParsedAsmOperand {
523 /// Broad categories of register classes
524 /// The exact class is finalized by the render method.
526 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
527 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
529 RegKind_FCC = 4, /// FCC
530 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
531 RegKind_MSACtrl = 16, /// MSA control registers
532 RegKind_COP2 = 32, /// COP2
533 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
535 RegKind_CCR = 128, /// CCR
536 RegKind_HWRegs = 256, /// HWRegs
537 RegKind_COP3 = 512, /// COP3
538 RegKind_COP0 = 1024, /// COP0
539 /// Potentially any (e.g. $1)
540 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
541 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
542 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
547 k_Immediate, /// An immediate (possibly involving symbol references)
548 k_Memory, /// Base + Offset Memory Address
549 k_PhysRegister, /// A physical register from the Mips namespace
550 k_RegisterIndex, /// A register index in one or more RegKind.
551 k_Token, /// A simple token
552 k_RegList, /// A physical register list
553 k_RegPair /// A pair of physical register
557 MipsOperand(KindTy K, MipsAsmParser &Parser)
558 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
561 /// For diagnostics, and checking the assembler temporary
562 MipsAsmParser &AsmParser;
570 unsigned Num; /// Register Number
574 unsigned Index; /// Index into the register class
575 RegKind Kind; /// Bitfield of the kinds it could possibly be
576 const MCRegisterInfo *RegInfo;
589 SmallVector<unsigned, 10> *List;
594 struct PhysRegOp PhysReg;
595 struct RegIdxOp RegIdx;
598 struct RegListOp RegList;
601 SMLoc StartLoc, EndLoc;
603 /// Internal constructor for register kinds
604 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
605 const MCRegisterInfo *RegInfo,
607 MipsAsmParser &Parser) {
608 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
609 Op->RegIdx.Index = Index;
610 Op->RegIdx.RegInfo = RegInfo;
611 Op->RegIdx.Kind = RegKind;
618 /// Coerce the register to GPR32 and return the real register for the current
620 unsigned getGPR32Reg() const {
621 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
622 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
623 unsigned ClassID = Mips::GPR32RegClassID;
624 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
627 /// Coerce the register to GPR32 and return the real register for the current
629 unsigned getGPRMM16Reg() const {
630 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
631 unsigned ClassID = Mips::GPR32RegClassID;
632 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
635 /// Coerce the register to GPR64 and return the real register for the current
637 unsigned getGPR64Reg() const {
638 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
639 unsigned ClassID = Mips::GPR64RegClassID;
640 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
644 /// Coerce the register to AFGR64 and return the real register for the current
646 unsigned getAFGR64Reg() const {
647 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
648 if (RegIdx.Index % 2 != 0)
649 AsmParser.Warning(StartLoc, "Float register should be even.");
650 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
651 .getRegister(RegIdx.Index / 2);
654 /// Coerce the register to FGR64 and return the real register for the current
656 unsigned getFGR64Reg() const {
657 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
658 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
659 .getRegister(RegIdx.Index);
662 /// Coerce the register to FGR32 and return the real register for the current
664 unsigned getFGR32Reg() const {
665 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
666 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
667 .getRegister(RegIdx.Index);
670 /// Coerce the register to FGRH32 and return the real register for the current
672 unsigned getFGRH32Reg() const {
673 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
674 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
675 .getRegister(RegIdx.Index);
678 /// Coerce the register to FCC and return the real register for the current
680 unsigned getFCCReg() const {
681 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
682 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
683 .getRegister(RegIdx.Index);
686 /// Coerce the register to MSA128 and return the real register for the current
688 unsigned getMSA128Reg() const {
689 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
690 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
692 unsigned ClassID = Mips::MSA128BRegClassID;
693 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
696 /// Coerce the register to MSACtrl and return the real register for the
698 unsigned getMSACtrlReg() const {
699 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
700 unsigned ClassID = Mips::MSACtrlRegClassID;
701 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
704 /// Coerce the register to COP0 and return the real register for the
706 unsigned getCOP0Reg() const {
707 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
708 unsigned ClassID = Mips::COP0RegClassID;
709 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
712 /// Coerce the register to COP2 and return the real register for the
714 unsigned getCOP2Reg() const {
715 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
716 unsigned ClassID = Mips::COP2RegClassID;
717 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
720 /// Coerce the register to COP3 and return the real register for the
722 unsigned getCOP3Reg() const {
723 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
724 unsigned ClassID = Mips::COP3RegClassID;
725 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
728 /// Coerce the register to ACC64DSP and return the real register for the
730 unsigned getACC64DSPReg() const {
731 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
732 unsigned ClassID = Mips::ACC64DSPRegClassID;
733 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
736 /// Coerce the register to HI32DSP and return the real register for the
738 unsigned getHI32DSPReg() const {
739 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
740 unsigned ClassID = Mips::HI32DSPRegClassID;
741 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
744 /// Coerce the register to LO32DSP and return the real register for the
746 unsigned getLO32DSPReg() const {
747 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
748 unsigned ClassID = Mips::LO32DSPRegClassID;
749 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
752 /// Coerce the register to CCR and return the real register for the
754 unsigned getCCRReg() const {
755 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
756 unsigned ClassID = Mips::CCRRegClassID;
757 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
760 /// Coerce the register to HWRegs and return the real register for the
762 unsigned getHWRegsReg() const {
763 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
764 unsigned ClassID = Mips::HWRegsRegClassID;
765 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
769 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
770 // Add as immediate when possible. Null MCExpr = 0.
772 Inst.addOperand(MCOperand::createImm(0));
773 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
774 Inst.addOperand(MCOperand::createImm(CE->getValue()));
776 Inst.addOperand(MCOperand::createExpr(Expr));
779 void addRegOperands(MCInst &Inst, unsigned N) const {
780 llvm_unreachable("Use a custom parser instead");
783 /// Render the operand to an MCInst as a GPR32
784 /// Asserts if the wrong number of operands are requested, or the operand
785 /// is not a k_RegisterIndex compatible with RegKind_GPR
786 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
787 assert(N == 1 && "Invalid number of operands!");
788 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
791 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
792 assert(N == 1 && "Invalid number of operands!");
793 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
796 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
797 assert(N == 1 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
801 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
802 assert(N == 1 && "Invalid number of operands!");
803 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
806 /// Render the operand to an MCInst as a GPR64
807 /// Asserts if the wrong number of operands are requested, or the operand
808 /// is not a k_RegisterIndex compatible with RegKind_GPR
809 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
810 assert(N == 1 && "Invalid number of operands!");
811 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
814 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
815 assert(N == 1 && "Invalid number of operands!");
816 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
819 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
820 assert(N == 1 && "Invalid number of operands!");
821 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
824 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
825 assert(N == 1 && "Invalid number of operands!");
826 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
827 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
828 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
829 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
833 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
834 assert(N == 1 && "Invalid number of operands!");
835 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
838 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
839 assert(N == 1 && "Invalid number of operands!");
840 Inst.addOperand(MCOperand::createReg(getFCCReg()));
843 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
844 assert(N == 1 && "Invalid number of operands!");
845 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
848 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
849 assert(N == 1 && "Invalid number of operands!");
850 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
853 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
854 assert(N == 1 && "Invalid number of operands!");
855 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
858 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
859 assert(N == 1 && "Invalid number of operands!");
860 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
863 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
864 assert(N == 1 && "Invalid number of operands!");
865 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
868 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
869 assert(N == 1 && "Invalid number of operands!");
870 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
873 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
874 assert(N == 1 && "Invalid number of operands!");
875 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
878 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
879 assert(N == 1 && "Invalid number of operands!");
880 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
883 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
884 assert(N == 1 && "Invalid number of operands!");
885 Inst.addOperand(MCOperand::createReg(getCCRReg()));
888 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
889 assert(N == 1 && "Invalid number of operands!");
890 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
893 void addImmOperands(MCInst &Inst, unsigned N) const {
894 assert(N == 1 && "Invalid number of operands!");
895 const MCExpr *Expr = getImm();
899 void addMemOperands(MCInst &Inst, unsigned N) const {
900 assert(N == 2 && "Invalid number of operands!");
902 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
903 ? getMemBase()->getGPR64Reg()
904 : getMemBase()->getGPR32Reg()));
906 const MCExpr *Expr = getMemOff();
910 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
911 assert(N == 2 && "Invalid number of operands!");
913 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
915 const MCExpr *Expr = getMemOff();
919 void addRegListOperands(MCInst &Inst, unsigned N) const {
920 assert(N == 1 && "Invalid number of operands!");
922 for (auto RegNo : getRegList())
923 Inst.addOperand(MCOperand::createReg(RegNo));
926 void addRegPairOperands(MCInst &Inst, unsigned N) const {
927 assert(N == 2 && "Invalid number of operands!");
928 unsigned RegNo = getRegPair();
929 Inst.addOperand(MCOperand::createReg(RegNo++));
930 Inst.addOperand(MCOperand::createReg(RegNo));
933 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
934 assert(N == 2 && "Invalid number of operands!");
935 for (auto RegNo : getRegList())
936 Inst.addOperand(MCOperand::createReg(RegNo));
939 bool isReg() const override {
940 // As a special case until we sort out the definition of div/divu, pretend
941 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
942 if (isGPRAsmReg() && RegIdx.Index == 0)
945 return Kind == k_PhysRegister;
947 bool isRegIdx() const { return Kind == k_RegisterIndex; }
948 bool isImm() const override { return Kind == k_Immediate; }
949 bool isConstantImm() const {
950 return isImm() && dyn_cast<MCConstantExpr>(getImm());
952 template <unsigned Bits> bool isUImm() const {
953 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
955 bool isToken() const override {
956 // Note: It's not possible to pretend that other operand kinds are tokens.
957 // The matcher emitter checks tokens first.
958 return Kind == k_Token;
960 bool isMem() const override { return Kind == k_Memory; }
961 bool isConstantMemOff() const {
962 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
964 template <unsigned Bits> bool isMemWithSimmOffset() const {
965 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
966 && getMemBase()->isGPRAsmReg();
968 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
969 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
970 getMemBase()->isGPRAsmReg();
972 bool isMemWithGRPMM16Base() const {
973 return isMem() && getMemBase()->isMM16AsmReg();
975 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
976 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
977 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
979 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
980 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
981 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
982 && (getMemBase()->getGPR32Reg() == Mips::SP);
984 bool isUImm5Lsl2() const {
985 return (isImm() && isConstantImm() && isShiftedUInt<5, 2>(getConstantImm()));
987 bool isRegList16() const {
991 int Size = RegList.List->size();
992 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
993 RegList.List->back() != Mips::RA)
996 int PrevReg = *RegList.List->begin();
997 for (int i = 1; i < Size - 1; i++) {
998 int Reg = (*(RegList.List))[i];
999 if ( Reg != PrevReg + 1)
1006 bool isInvNum() const { return Kind == k_Immediate; }
1007 bool isLSAImm() const {
1008 if (!isConstantImm())
1010 int64_t Val = getConstantImm();
1011 return 1 <= Val && Val <= 4;
1013 bool isRegList() const { return Kind == k_RegList; }
1014 bool isMovePRegPair() const {
1015 if (Kind != k_RegList || RegList.List->size() != 2)
1018 unsigned R0 = RegList.List->front();
1019 unsigned R1 = RegList.List->back();
1021 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1022 (R0 == Mips::A1 && R1 == Mips::A3) ||
1023 (R0 == Mips::A2 && R1 == Mips::A3) ||
1024 (R0 == Mips::A0 && R1 == Mips::S5) ||
1025 (R0 == Mips::A0 && R1 == Mips::S6) ||
1026 (R0 == Mips::A0 && R1 == Mips::A1) ||
1027 (R0 == Mips::A0 && R1 == Mips::A2) ||
1028 (R0 == Mips::A0 && R1 == Mips::A3))
1034 StringRef getToken() const {
1035 assert(Kind == k_Token && "Invalid access!");
1036 return StringRef(Tok.Data, Tok.Length);
1038 bool isRegPair() const { return Kind == k_RegPair; }
1040 unsigned getReg() const override {
1041 // As a special case until we sort out the definition of div/divu, pretend
1042 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1043 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1044 RegIdx.Kind & RegKind_GPR)
1045 return getGPR32Reg(); // FIXME: GPR64 too
1047 assert(Kind == k_PhysRegister && "Invalid access!");
1051 const MCExpr *getImm() const {
1052 assert((Kind == k_Immediate) && "Invalid access!");
1056 int64_t getConstantImm() const {
1057 const MCExpr *Val = getImm();
1058 return static_cast<const MCConstantExpr *>(Val)->getValue();
1061 MipsOperand *getMemBase() const {
1062 assert((Kind == k_Memory) && "Invalid access!");
1066 const MCExpr *getMemOff() const {
1067 assert((Kind == k_Memory) && "Invalid access!");
1071 int64_t getConstantMemOff() const {
1072 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1075 const SmallVectorImpl<unsigned> &getRegList() const {
1076 assert((Kind == k_RegList) && "Invalid access!");
1077 return *(RegList.List);
1080 unsigned getRegPair() const {
1081 assert((Kind == k_RegPair) && "Invalid access!");
1082 return RegIdx.Index;
1085 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1086 MipsAsmParser &Parser) {
1087 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1088 Op->Tok.Data = Str.data();
1089 Op->Tok.Length = Str.size();
1095 /// Create a numeric register (e.g. $1). The exact register remains
1096 /// unresolved until an instruction successfully matches
1097 static std::unique_ptr<MipsOperand>
1098 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1099 SMLoc E, MipsAsmParser &Parser) {
1100 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1101 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1104 /// Create a register that is definitely a GPR.
1105 /// This is typically only used for named registers such as $gp.
1106 static std::unique_ptr<MipsOperand>
1107 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1108 MipsAsmParser &Parser) {
1109 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1112 /// Create a register that is definitely a FGR.
1113 /// This is typically only used for named registers such as $f0.
1114 static std::unique_ptr<MipsOperand>
1115 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1116 MipsAsmParser &Parser) {
1117 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1120 /// Create a register that is definitely a HWReg.
1121 /// This is typically only used for named registers such as $hwr_cpunum.
1122 static std::unique_ptr<MipsOperand>
1123 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1124 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1125 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1128 /// Create a register that is definitely an FCC.
1129 /// This is typically only used for named registers such as $fcc0.
1130 static std::unique_ptr<MipsOperand>
1131 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1132 MipsAsmParser &Parser) {
1133 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1136 /// Create a register that is definitely an ACC.
1137 /// This is typically only used for named registers such as $ac0.
1138 static std::unique_ptr<MipsOperand>
1139 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1140 MipsAsmParser &Parser) {
1141 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1144 /// Create a register that is definitely an MSA128.
1145 /// This is typically only used for named registers such as $w0.
1146 static std::unique_ptr<MipsOperand>
1147 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1148 SMLoc E, MipsAsmParser &Parser) {
1149 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1152 /// Create a register that is definitely an MSACtrl.
1153 /// This is typically only used for named registers such as $msaaccess.
1154 static std::unique_ptr<MipsOperand>
1155 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1156 SMLoc E, MipsAsmParser &Parser) {
1157 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1160 static std::unique_ptr<MipsOperand>
1161 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1162 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1169 static std::unique_ptr<MipsOperand>
1170 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1171 SMLoc E, MipsAsmParser &Parser) {
1172 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1173 Op->Mem.Base = Base.release();
1180 static std::unique_ptr<MipsOperand>
1181 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1182 MipsAsmParser &Parser) {
1183 assert (Regs.size() > 0 && "Empty list not allowed");
1185 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1186 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1187 Op->StartLoc = StartLoc;
1188 Op->EndLoc = EndLoc;
1192 static std::unique_ptr<MipsOperand>
1193 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1194 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1195 Op->RegIdx.Index = RegNo;
1201 bool isGPRAsmReg() const {
1202 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1204 bool isMM16AsmReg() const {
1205 if (!(isRegIdx() && RegIdx.Kind))
1207 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1208 || RegIdx.Index == 16 || RegIdx.Index == 17);
1210 bool isMM16AsmRegZero() const {
1211 if (!(isRegIdx() && RegIdx.Kind))
1213 return (RegIdx.Index == 0 ||
1214 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1215 RegIdx.Index == 17);
1217 bool isMM16AsmRegMoveP() const {
1218 if (!(isRegIdx() && RegIdx.Kind))
1220 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1221 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1223 bool isFGRAsmReg() const {
1224 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1225 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1227 bool isHWRegsAsmReg() const {
1228 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1230 bool isCCRAsmReg() const {
1231 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1233 bool isFCCAsmReg() const {
1234 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1236 if (!AsmParser.hasEightFccRegisters())
1237 return RegIdx.Index == 0;
1238 return RegIdx.Index <= 7;
1240 bool isACCAsmReg() const {
1241 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1243 bool isCOP0AsmReg() const {
1244 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1246 bool isCOP2AsmReg() const {
1247 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1249 bool isCOP3AsmReg() const {
1250 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1252 bool isMSA128AsmReg() const {
1253 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1255 bool isMSACtrlAsmReg() const {
1256 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1259 /// getStartLoc - Get the location of the first token of this operand.
1260 SMLoc getStartLoc() const override { return StartLoc; }
1261 /// getEndLoc - Get the location of the last token of this operand.
1262 SMLoc getEndLoc() const override { return EndLoc; }
1264 virtual ~MipsOperand() {
1272 delete RegList.List;
1273 case k_PhysRegister:
1274 case k_RegisterIndex:
1281 void print(raw_ostream &OS) const override {
1290 Mem.Base->print(OS);
1295 case k_PhysRegister:
1296 OS << "PhysReg<" << PhysReg.Num << ">";
1298 case k_RegisterIndex:
1299 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1306 for (auto Reg : (*RegList.List))
1311 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1315 }; // class MipsOperand
1319 extern const MCInstrDesc MipsInsts[];
1321 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1322 return MipsInsts[Opcode];
1325 static bool hasShortDelaySlot(unsigned Opcode) {
1328 case Mips::JALRS_MM:
1329 case Mips::JALRS16_MM:
1330 case Mips::BGEZALS_MM:
1331 case Mips::BLTZALS_MM:
1338 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1339 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1340 return &SRExpr->getSymbol();
1343 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1344 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1345 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1356 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1357 return getSingleMCSymbol(UExpr->getSubExpr());
1362 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1363 if (isa<MCSymbolRefExpr>(Expr))
1366 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1367 return countMCSymbolRefExpr(BExpr->getLHS()) +
1368 countMCSymbolRefExpr(BExpr->getRHS());
1370 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1371 return countMCSymbolRefExpr(UExpr->getSubExpr());
1377 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1378 SmallVectorImpl<MCInst> &Instructions) {
1380 tmpInst.setOpcode(Opcode);
1381 tmpInst.addOperand(MCOperand::createReg(Reg0));
1382 tmpInst.addOperand(Op1);
1383 tmpInst.setLoc(IDLoc);
1384 Instructions.push_back(tmpInst);
1387 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1388 SmallVectorImpl<MCInst> &Instructions) {
1389 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1392 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1393 SmallVectorImpl<MCInst> &Instructions) {
1394 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1397 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1398 SmallVectorImpl<MCInst> &Instructions) {
1400 tmpInst.setOpcode(Opcode);
1401 tmpInst.addOperand(MCOperand::createImm(Imm1));
1402 tmpInst.addOperand(MCOperand::createImm(Imm2));
1403 tmpInst.setLoc(IDLoc);
1404 Instructions.push_back(tmpInst);
1407 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1408 SmallVectorImpl<MCInst> &Instructions) {
1410 tmpInst.setOpcode(Opcode);
1411 tmpInst.addOperand(MCOperand::createReg(Reg0));
1412 tmpInst.setLoc(IDLoc);
1413 Instructions.push_back(tmpInst);
1416 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1417 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1419 tmpInst.setOpcode(Opcode);
1420 tmpInst.addOperand(MCOperand::createReg(Reg0));
1421 tmpInst.addOperand(MCOperand::createReg(Reg1));
1422 tmpInst.addOperand(Op2);
1423 tmpInst.setLoc(IDLoc);
1424 Instructions.push_back(tmpInst);
1427 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1428 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1429 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1433 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1434 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1435 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1439 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1440 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1441 if (ShiftAmount >= 32) {
1442 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1447 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1449 } // end anonymous namespace.
1451 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1452 SmallVectorImpl<MCInst> &Instructions) {
1453 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1454 bool ExpandedJalSym = false;
1458 if (MCID.isBranch() || MCID.isCall()) {
1459 const unsigned Opcode = Inst.getOpcode();
1469 assert(hasCnMips() && "instruction only valid for octeon cpus");
1476 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1477 Offset = Inst.getOperand(2);
1478 if (!Offset.isImm())
1479 break; // We'll deal with this situation later on when applying fixups.
1480 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1481 return Error(IDLoc, "branch target out of range");
1482 if (OffsetToAlignment(Offset.getImm(),
1483 1LL << (inMicroMipsMode() ? 1 : 2)))
1484 return Error(IDLoc, "branch to misaligned address");
1498 case Mips::BGEZAL_MM:
1499 case Mips::BLTZAL_MM:
1502 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1503 Offset = Inst.getOperand(1);
1504 if (!Offset.isImm())
1505 break; // We'll deal with this situation later on when applying fixups.
1506 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1507 return Error(IDLoc, "branch target out of range");
1508 if (OffsetToAlignment(Offset.getImm(),
1509 1LL << (inMicroMipsMode() ? 1 : 2)))
1510 return Error(IDLoc, "branch to misaligned address");
1512 case Mips::BEQZ16_MM:
1513 case Mips::BEQZC16_MMR6:
1514 case Mips::BNEZ16_MM:
1515 case Mips::BNEZC16_MMR6:
1516 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1517 Offset = Inst.getOperand(1);
1518 if (!Offset.isImm())
1519 break; // We'll deal with this situation later on when applying fixups.
1520 if (!isInt<8>(Offset.getImm()))
1521 return Error(IDLoc, "branch target out of range");
1522 if (OffsetToAlignment(Offset.getImm(), 2LL))
1523 return Error(IDLoc, "branch to misaligned address");
1528 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1529 // We still accept it but it is a normal nop.
1530 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1531 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1532 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1537 const unsigned Opcode = Inst.getOpcode();
1549 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1550 // The offset is handled above
1551 Opnd = Inst.getOperand(1);
1553 return Error(IDLoc, "expected immediate operand kind");
1554 Imm = Opnd.getImm();
1555 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1556 Opcode == Mips::BBIT1 ? 63 : 31))
1557 return Error(IDLoc, "immediate operand value out of range");
1559 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1561 Inst.getOperand(1).setImm(Imm - 32);
1569 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1571 Opnd = Inst.getOperand(3);
1573 return Error(IDLoc, "expected immediate operand kind");
1574 Imm = Opnd.getImm();
1575 if (Imm < 0 || Imm > 31)
1576 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 (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1583 Opcode == Mips::EXTS ? 63 : 31))
1584 return Error(IDLoc, "immediate operand value out of range");
1586 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1587 Inst.getOperand(2).setImm(Imm - 32);
1593 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1594 Opnd = Inst.getOperand(2);
1596 return Error(IDLoc, "expected immediate operand kind");
1597 Imm = Opnd.getImm();
1598 if (!isInt<10>(Imm))
1599 return Error(IDLoc, "immediate operand value out of range");
1604 // This expansion is not in a function called by expandInstruction() because
1605 // the pseudo-instruction doesn't have a distinct opcode.
1606 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1608 warnIfNoMacro(IDLoc);
1610 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1612 // We can do this expansion if there's only 1 symbol in the argument
1614 if (countMCSymbolRefExpr(JalExpr) > 1)
1615 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1617 // FIXME: This is checking the expression can be handled by the later stages
1618 // of the assembler. We ought to leave it to those later stages but
1619 // we can't do that until we stop evaluateRelocExpr() rewriting the
1620 // expressions into non-equivalent forms.
1621 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1623 // FIXME: Add support for label+offset operands (currently causes an error).
1624 // FIXME: Add support for forward-declared local symbols.
1625 // FIXME: Add expansion for when the LargeGOT option is enabled.
1626 if (JalSym->isInSection() || JalSym->isTemporary()) {
1628 // If it's a local symbol and the O32 ABI is being used, we expand to:
1630 // R_(MICRO)MIPS_GOT16 label
1631 // addiu $25, $25, 0
1632 // R_(MICRO)MIPS_LO16 label
1634 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1635 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1637 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1638 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1639 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1640 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1641 } else if (isABI_N32() || isABI_N64()) {
1642 // If it's a local symbol and the N32/N64 ABIs are being used,
1644 // lw/ld $25, 0($gp)
1645 // R_(MICRO)MIPS_GOT_DISP label
1647 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1649 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1650 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1653 // If it's an external/weak symbol, we expand to:
1654 // lw/ld $25, 0($gp)
1655 // R_(MICRO)MIPS_CALL16 label
1657 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1659 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1660 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1664 if (IsCpRestoreSet && inMicroMipsMode())
1665 JalrInst.setOpcode(Mips::JALRS_MM);
1667 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1668 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1669 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1671 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1672 // This relocation is supposed to be an optimization hint for the linker
1673 // and is not necessary for correctness.
1676 ExpandedJalSym = true;
1679 if (MCID.mayLoad() || MCID.mayStore()) {
1680 // Check the offset of memory operand, if it is a symbol
1681 // reference or immediate we may have to expand instructions.
1682 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1683 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1684 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1685 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1686 MCOperand &Op = Inst.getOperand(i);
1688 int MemOffset = Op.getImm();
1689 if (MemOffset < -32768 || MemOffset > 32767) {
1690 // Offset can't exceed 16bit value.
1691 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1694 } else if (Op.isExpr()) {
1695 const MCExpr *Expr = Op.getExpr();
1696 if (Expr->getKind() == MCExpr::SymbolRef) {
1697 const MCSymbolRefExpr *SR =
1698 static_cast<const MCSymbolRefExpr *>(Expr);
1699 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1701 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1704 } else if (!isEvaluated(Expr)) {
1705 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1713 if (inMicroMipsMode()) {
1714 if (MCID.mayLoad()) {
1715 // Try to create 16-bit GP relative load instruction.
1716 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1717 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1718 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1719 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1720 MCOperand &Op = Inst.getOperand(i);
1722 int MemOffset = Op.getImm();
1723 MCOperand &DstReg = Inst.getOperand(0);
1724 MCOperand &BaseReg = Inst.getOperand(1);
1725 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1726 getContext().getRegisterInfo()->getRegClass(
1727 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1728 (BaseReg.getReg() == Mips::GP ||
1729 BaseReg.getReg() == Mips::GP_64)) {
1731 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1732 IDLoc, Instructions);
1740 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1745 switch (Inst.getOpcode()) {
1748 case Mips::ADDIUS5_MM:
1749 Opnd = Inst.getOperand(2);
1751 return Error(IDLoc, "expected immediate operand kind");
1752 Imm = Opnd.getImm();
1753 if (Imm < -8 || Imm > 7)
1754 return Error(IDLoc, "immediate operand value out of range");
1756 case Mips::ADDIUSP_MM:
1757 Opnd = Inst.getOperand(0);
1759 return Error(IDLoc, "expected immediate operand kind");
1760 Imm = Opnd.getImm();
1761 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1763 return Error(IDLoc, "immediate operand value out of range");
1765 case Mips::SLL16_MM:
1766 case Mips::SRL16_MM:
1767 Opnd = Inst.getOperand(2);
1769 return Error(IDLoc, "expected immediate operand kind");
1770 Imm = Opnd.getImm();
1771 if (Imm < 1 || Imm > 8)
1772 return Error(IDLoc, "immediate operand value out of range");
1775 Opnd = Inst.getOperand(1);
1777 return Error(IDLoc, "expected immediate operand kind");
1778 Imm = Opnd.getImm();
1779 if (Imm < -1 || Imm > 126)
1780 return Error(IDLoc, "immediate operand value out of range");
1782 case Mips::ADDIUR2_MM:
1783 Opnd = Inst.getOperand(2);
1785 return Error(IDLoc, "expected immediate operand kind");
1786 Imm = Opnd.getImm();
1787 if (!(Imm == 1 || Imm == -1 ||
1788 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1789 return Error(IDLoc, "immediate operand value out of range");
1791 case Mips::ADDIUR1SP_MM:
1792 Opnd = Inst.getOperand(1);
1794 return Error(IDLoc, "expected immediate operand kind");
1795 Imm = Opnd.getImm();
1796 if (OffsetToAlignment(Imm, 4LL))
1797 return Error(IDLoc, "misaligned immediate operand value");
1798 if (Imm < 0 || Imm > 255)
1799 return Error(IDLoc, "immediate operand value out of range");
1801 case Mips::ANDI16_MM:
1802 Opnd = Inst.getOperand(2);
1804 return Error(IDLoc, "expected immediate operand kind");
1805 Imm = Opnd.getImm();
1806 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1807 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1808 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1809 return Error(IDLoc, "immediate operand value out of range");
1811 case Mips::LBU16_MM:
1812 Opnd = Inst.getOperand(2);
1814 return Error(IDLoc, "expected immediate operand kind");
1815 Imm = Opnd.getImm();
1816 if (Imm < -1 || Imm > 14)
1817 return Error(IDLoc, "immediate operand value out of range");
1826 Opnd = Inst.getOperand(2);
1828 return Error(IDLoc, "expected immediate operand kind");
1829 Imm = Opnd.getImm();
1830 if (Imm < 0 || Imm > 15)
1831 return Error(IDLoc, "immediate operand value out of range");
1833 case Mips::LHU16_MM:
1835 Opnd = Inst.getOperand(2);
1837 return Error(IDLoc, "expected immediate operand kind");
1838 Imm = Opnd.getImm();
1839 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1840 return Error(IDLoc, "immediate operand value out of range");
1844 Opnd = Inst.getOperand(2);
1846 return Error(IDLoc, "expected immediate operand kind");
1847 Imm = Opnd.getImm();
1848 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1849 return Error(IDLoc, "immediate operand value out of range");
1851 case Mips::PREFX_MM:
1854 Opnd = Inst.getOperand(2);
1856 return Error(IDLoc, "expected immediate operand kind");
1857 Imm = Opnd.getImm();
1858 if (!isUInt<5>(Imm))
1859 return Error(IDLoc, "immediate operand value out of range");
1861 case Mips::ADDIUPC_MM:
1862 MCOperand Opnd = Inst.getOperand(1);
1864 return Error(IDLoc, "expected immediate operand kind");
1865 int Imm = Opnd.getImm();
1866 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1867 return Error(IDLoc, "immediate operand value out of range");
1872 if (needsExpansion(Inst)) {
1873 if (expandInstruction(Inst, IDLoc, Instructions))
1876 Instructions.push_back(Inst);
1878 // If this instruction has a delay slot and .set reorder is active,
1879 // emit a NOP after it.
1880 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1881 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1883 if ((Inst.getOpcode() == Mips::JalOneReg ||
1884 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1885 isPicAndNotNxxAbi()) {
1886 if (IsCpRestoreSet) {
1887 // We need a NOP between the JALR and the LW:
1888 // If .set reorder has been used, we've already emitted a NOP.
1889 // If .set noreorder has been used, we need to emit a NOP at this point.
1890 if (!AssemblerOptions.back()->isReorder())
1891 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1893 // Load the $gp from the stack.
1894 SmallVector<MCInst, 3> LoadInsts;
1895 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1898 for (const MCInst &Inst : LoadInsts)
1899 Instructions.push_back(Inst);
1902 Warning(IDLoc, "no .cprestore used in PIC mode");
1908 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1910 switch (Inst.getOpcode()) {
1911 case Mips::LoadImm32:
1912 case Mips::LoadImm64:
1913 case Mips::LoadAddrImm32:
1914 case Mips::LoadAddrImm64:
1915 case Mips::LoadAddrReg32:
1916 case Mips::LoadAddrReg64:
1917 case Mips::B_MM_Pseudo:
1918 case Mips::B_MMR6_Pseudo:
1921 case Mips::JalOneReg:
1922 case Mips::JalTwoReg:
1941 case Mips::BLTImmMacro:
1942 case Mips::BLEImmMacro:
1943 case Mips::BGEImmMacro:
1944 case Mips::BGTImmMacro:
1945 case Mips::BLTUImmMacro:
1946 case Mips::BLEUImmMacro:
1947 case Mips::BGEUImmMacro:
1948 case Mips::BGTUImmMacro:
1949 case Mips::BLTLImmMacro:
1950 case Mips::BLELImmMacro:
1951 case Mips::BGELImmMacro:
1952 case Mips::BGTLImmMacro:
1953 case Mips::BLTULImmMacro:
1954 case Mips::BLEULImmMacro:
1955 case Mips::BGEULImmMacro:
1956 case Mips::BGTULImmMacro:
1957 case Mips::SDivMacro:
1958 case Mips::UDivMacro:
1959 case Mips::DSDivMacro:
1960 case Mips::DUDivMacro:
1969 if ((Inst.getNumOperands() == 3) &&
1970 Inst.getOperand(0).isReg() &&
1971 Inst.getOperand(1).isReg() &&
1972 Inst.getOperand(2).isImm()) {
1973 int64_t ImmValue = Inst.getOperand(2).getImm();
1974 return !isInt<16>(ImmValue);
1980 if ((Inst.getNumOperands() == 3) &&
1981 Inst.getOperand(0).isReg() &&
1982 Inst.getOperand(1).isReg() &&
1983 Inst.getOperand(2).isImm()) {
1984 int64_t ImmValue = Inst.getOperand(2).getImm();
1985 return !isUInt<16>(ImmValue);
1993 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1994 SmallVectorImpl<MCInst> &Instructions) {
1995 switch (Inst.getOpcode()) {
1996 default: llvm_unreachable("unimplemented expansion");
1997 case Mips::LoadImm32:
1998 return expandLoadImm(Inst, true, IDLoc, Instructions);
1999 case Mips::LoadImm64:
2000 return expandLoadImm(Inst, false, IDLoc, Instructions);
2001 case Mips::LoadAddrImm32:
2002 case Mips::LoadAddrImm64:
2003 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2004 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2005 "expected immediate operand kind");
2007 return expandLoadAddress(
2008 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
2009 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
2010 case Mips::LoadAddrReg32:
2011 case Mips::LoadAddrReg64:
2012 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2013 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2014 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2015 "expected immediate operand kind");
2017 return expandLoadAddress(
2018 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
2019 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
2020 case Mips::B_MM_Pseudo:
2021 case Mips::B_MMR6_Pseudo:
2022 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
2025 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
2026 case Mips::JalOneReg:
2027 case Mips::JalTwoReg:
2028 return expandJalWithRegs(Inst, IDLoc, Instructions);
2031 return expandBranchImm(Inst, IDLoc, Instructions);
2048 case Mips::BLTImmMacro:
2049 case Mips::BLEImmMacro:
2050 case Mips::BGEImmMacro:
2051 case Mips::BGTImmMacro:
2052 case Mips::BLTUImmMacro:
2053 case Mips::BLEUImmMacro:
2054 case Mips::BGEUImmMacro:
2055 case Mips::BGTUImmMacro:
2056 case Mips::BLTLImmMacro:
2057 case Mips::BLELImmMacro:
2058 case Mips::BGELImmMacro:
2059 case Mips::BGTLImmMacro:
2060 case Mips::BLTULImmMacro:
2061 case Mips::BLEULImmMacro:
2062 case Mips::BGEULImmMacro:
2063 case Mips::BGTULImmMacro:
2064 return expandCondBranches(Inst, IDLoc, Instructions);
2065 case Mips::SDivMacro:
2066 return expandDiv(Inst, IDLoc, Instructions, false, true);
2067 case Mips::DSDivMacro:
2068 return expandDiv(Inst, IDLoc, Instructions, true, true);
2069 case Mips::UDivMacro:
2070 return expandDiv(Inst, IDLoc, Instructions, false, false);
2071 case Mips::DUDivMacro:
2072 return expandDiv(Inst, IDLoc, Instructions, true, false);
2074 return expandUlhu(Inst, IDLoc, Instructions);
2076 return expandUlw(Inst, IDLoc, Instructions);
2085 return expandAliasImmediate(Inst, IDLoc, Instructions);
2089 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2090 SmallVectorImpl<MCInst> &Instructions) {
2091 // Create a JALR instruction which is going to replace the pseudo-JAL.
2093 JalrInst.setLoc(IDLoc);
2094 const MCOperand FirstRegOp = Inst.getOperand(0);
2095 const unsigned Opcode = Inst.getOpcode();
2097 if (Opcode == Mips::JalOneReg) {
2098 // jal $rs => jalr $rs
2099 if (IsCpRestoreSet && inMicroMipsMode()) {
2100 JalrInst.setOpcode(Mips::JALRS16_MM);
2101 JalrInst.addOperand(FirstRegOp);
2102 } else if (inMicroMipsMode()) {
2103 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2104 JalrInst.addOperand(FirstRegOp);
2106 JalrInst.setOpcode(Mips::JALR);
2107 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2108 JalrInst.addOperand(FirstRegOp);
2110 } else if (Opcode == Mips::JalTwoReg) {
2111 // jal $rd, $rs => jalr $rd, $rs
2112 if (IsCpRestoreSet && inMicroMipsMode())
2113 JalrInst.setOpcode(Mips::JALRS_MM);
2115 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2116 JalrInst.addOperand(FirstRegOp);
2117 const MCOperand SecondRegOp = Inst.getOperand(1);
2118 JalrInst.addOperand(SecondRegOp);
2120 Instructions.push_back(JalrInst);
2122 // If .set reorder is active and branch instruction has a delay slot,
2123 // emit a NOP after it.
2124 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2125 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2126 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2132 /// Can the value be represented by a unsigned N-bit value and a shift left?
2133 template<unsigned N>
2134 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2135 unsigned BitNum = findFirstSet(x);
2137 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2140 /// Load (or add) an immediate into a register.
2142 /// @param ImmValue The immediate to load.
2143 /// @param DstReg The register that will hold the immediate.
2144 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2145 /// for a simple initialization.
2146 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2147 /// @param IsAddress True if the immediate represents an address. False if it
2149 /// @param IDLoc Location of the immediate in the source file.
2150 /// @param Instructions The instructions emitted by this expansion.
2151 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2152 unsigned SrcReg, bool Is32BitImm,
2153 bool IsAddress, SMLoc IDLoc,
2154 SmallVectorImpl<MCInst> &Instructions) {
2155 if (!Is32BitImm && !isGP64bit()) {
2156 Error(IDLoc, "instruction requires a 64-bit architecture");
2161 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2162 // Sign extend up to 64-bit so that the predicates match the hardware
2163 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2165 ImmValue = SignExtend64<32>(ImmValue);
2167 Error(IDLoc, "instruction requires a 32-bit immediate");
2172 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2173 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2175 bool UseSrcReg = false;
2176 if (SrcReg != Mips::NoRegister)
2179 unsigned TmpReg = DstReg;
2180 if (UseSrcReg && (DstReg == SrcReg)) {
2181 // At this point we need AT to perform the expansions and we exit if it is
2183 unsigned ATReg = getATReg(IDLoc);
2189 if (isInt<16>(ImmValue)) {
2193 // This doesn't quite follow the usual ABI expectations for N32 but matches
2194 // traditional assembler behaviour. N32 would normally use addiu for both
2195 // integers and addresses.
2196 if (IsAddress && !Is32BitImm) {
2197 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2201 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2205 if (isUInt<16>(ImmValue)) {
2206 unsigned TmpReg = DstReg;
2207 if (SrcReg == DstReg) {
2208 TmpReg = getATReg(IDLoc);
2213 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2215 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2219 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2220 warnIfNoMacro(IDLoc);
2222 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2223 uint16_t Bits15To0 = ImmValue & 0xffff;
2225 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2226 // Traditional behaviour seems to special case this particular value. It's
2227 // not clear why other masks are handled differently.
2228 if (ImmValue == 0xffffffff) {
2229 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2230 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2232 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2236 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2238 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2239 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2241 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2243 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2247 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2249 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2251 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2255 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2257 Error(IDLoc, "instruction requires a 32-bit immediate");
2261 // Traditionally, these immediates are shifted as little as possible and as
2262 // such we align the most significant bit to bit 15 of our temporary.
2263 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2264 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2265 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2266 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2267 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2268 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2271 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2276 warnIfNoMacro(IDLoc);
2278 // The remaining case is packed with a sequence of dsll and ori with zeros
2279 // being omitted and any neighbouring dsll's being coalesced.
2280 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2282 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2283 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2284 IDLoc, Instructions))
2287 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2288 // skip it and defer the shift to the next chunk.
2289 unsigned ShiftCarriedForwards = 16;
2290 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2291 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2293 if (ImmChunk != 0) {
2294 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2296 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2297 ShiftCarriedForwards = 0;
2300 ShiftCarriedForwards += 16;
2302 ShiftCarriedForwards -= 16;
2304 // Finish any remaining shifts left by trailing zeros.
2305 if (ShiftCarriedForwards)
2306 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2310 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2315 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2316 SmallVectorImpl<MCInst> &Instructions) {
2317 const MCOperand &ImmOp = Inst.getOperand(1);
2318 assert(ImmOp.isImm() && "expected immediate operand kind");
2319 const MCOperand &DstRegOp = Inst.getOperand(0);
2320 assert(DstRegOp.isReg() && "expected register operand kind");
2322 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2323 Is32BitImm, false, IDLoc, Instructions))
2329 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2330 const MCOperand &Offset,
2331 bool Is32BitAddress, SMLoc IDLoc,
2332 SmallVectorImpl<MCInst> &Instructions) {
2333 // la can't produce a usable address when addresses are 64-bit.
2334 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2335 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2336 // We currently can't do this because we depend on the equality
2337 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2338 Error(IDLoc, "la used to load 64-bit address");
2339 // Continue as if we had 'dla' instead.
2340 Is32BitAddress = false;
2343 // dla requires 64-bit addresses.
2344 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2345 Error(IDLoc, "instruction requires a 64-bit architecture");
2349 if (!Offset.isImm())
2350 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2351 Is32BitAddress, IDLoc, Instructions);
2353 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2354 IDLoc, Instructions);
2357 bool MipsAsmParser::loadAndAddSymbolAddress(
2358 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2359 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2360 warnIfNoMacro(IDLoc);
2362 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2363 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2364 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2365 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2366 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2368 bool UseSrcReg = SrcReg != Mips::NoRegister;
2370 // This is the 64-bit symbol address expansion.
2371 if (ABI.ArePtrs64bit() && isGP64bit()) {
2372 // We always need AT for the 64-bit expansion.
2373 // If it is not available we exit.
2374 unsigned ATReg = getATReg(IDLoc);
2378 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2379 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2380 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2381 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2383 if (UseSrcReg && (DstReg == SrcReg)) {
2384 // If $rs is the same as $rd:
2385 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2386 // daddiu $at, $at, %higher(sym)
2387 // dsll $at, $at, 16
2388 // daddiu $at, $at, %hi(sym)
2389 // dsll $at, $at, 16
2390 // daddiu $at, $at, %lo(sym)
2391 // daddu $rd, $at, $rd
2392 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2394 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2395 IDLoc, Instructions);
2396 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2397 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2399 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2400 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2402 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2407 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2408 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2409 // lui $at, %hi(sym)
2410 // daddiu $rd, $rd, %higher(sym)
2411 // daddiu $at, $at, %lo(sym)
2412 // dsll32 $rd, $rd, 0
2413 // daddu $rd, $rd, $at
2414 // (daddu $rd, $rd, $rs)
2415 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2417 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2419 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2420 IDLoc, Instructions);
2421 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2423 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2424 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2426 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2431 // And now, the 32-bit symbol address expansion:
2432 // If $rs is the same as $rd:
2433 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2434 // ori $at, $at, %lo(sym)
2435 // addu $rd, $at, $rd
2436 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2437 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2438 // ori $rd, $rd, %lo(sym)
2439 // (addu $rd, $rd, $rs)
2440 unsigned TmpReg = DstReg;
2441 if (UseSrcReg && (DstReg == SrcReg)) {
2442 // If $rs is the same as $rd, we need to use AT.
2443 // If it is not available we exit.
2444 unsigned ATReg = getATReg(IDLoc);
2450 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2451 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2455 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2457 assert(DstReg == TmpReg);
2462 bool MipsAsmParser::expandUncondBranchMMPseudo(
2463 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2464 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2465 "unexpected number of operands");
2467 MCOperand Offset = Inst.getOperand(0);
2468 if (Offset.isExpr()) {
2470 Inst.setOpcode(Mips::BEQ_MM);
2471 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2472 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2473 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2475 assert(Offset.isImm() && "expected immediate operand kind");
2476 if (isInt<11>(Offset.getImm())) {
2477 // If offset fits into 11 bits then this instruction becomes microMIPS
2478 // 16-bit unconditional branch instruction.
2479 if (inMicroMipsMode())
2480 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2482 if (!isInt<17>(Offset.getImm()))
2483 Error(IDLoc, "branch target out of range");
2484 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2485 Error(IDLoc, "branch to misaligned address");
2487 Inst.setOpcode(Mips::BEQ_MM);
2488 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2489 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2490 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2493 Instructions.push_back(Inst);
2495 // If .set reorder is active and branch instruction has a delay slot,
2496 // emit a NOP after it.
2497 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2498 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2499 createNop(true, IDLoc, Instructions);
2504 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2505 SmallVectorImpl<MCInst> &Instructions) {
2506 const MCOperand &DstRegOp = Inst.getOperand(0);
2507 assert(DstRegOp.isReg() && "expected register operand kind");
2509 const MCOperand &ImmOp = Inst.getOperand(1);
2510 assert(ImmOp.isImm() && "expected immediate operand kind");
2512 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2513 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2515 unsigned OpCode = 0;
2516 switch(Inst.getOpcode()) {
2524 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2528 int64_t ImmValue = ImmOp.getImm();
2530 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2533 warnIfNoMacro(IDLoc);
2535 unsigned ATReg = getATReg(IDLoc);
2539 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2540 IDLoc, Instructions))
2543 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2548 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2549 SmallVectorImpl<MCInst> &Instructions,
2550 bool isLoad, bool isImmOpnd) {
2551 unsigned ImmOffset, HiOffset, LoOffset;
2552 const MCExpr *ExprOffset;
2554 // 1st operand is either the source or destination register.
2555 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2556 unsigned RegOpNum = Inst.getOperand(0).getReg();
2557 // 2nd operand is the base register.
2558 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2559 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2560 // 3rd operand is either an immediate or expression.
2562 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2563 ImmOffset = Inst.getOperand(2).getImm();
2564 LoOffset = ImmOffset & 0x0000ffff;
2565 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2566 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2567 if (LoOffset & 0x8000)
2570 ExprOffset = Inst.getOperand(2).getExpr();
2571 // These are some of the types of expansions we perform here:
2572 // 1) lw $8, sym => lui $8, %hi(sym)
2573 // lw $8, %lo(sym)($8)
2574 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2576 // lw $8, %lo(offset)($9)
2577 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2579 // lw $8, %lo(offset)($at)
2580 // 4) sw $8, sym => lui $at, %hi(sym)
2581 // sw $8, %lo(sym)($at)
2582 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2584 // sw $8, %lo(offset)($at)
2585 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2586 // ldc1 $f0, %lo(sym)($at)
2588 // For load instructions we can use the destination register as a temporary
2589 // if base and dst are different (examples 1 and 2) and if the base register
2590 // is general purpose otherwise we must use $at (example 6) and error if it's
2591 // not available. For stores we must use $at (examples 4 and 5) because we
2592 // must not clobber the source register setting up the offset.
2593 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2594 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2595 unsigned RegClassIDOp0 =
2596 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2597 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2598 (RegClassIDOp0 == Mips::GPR64RegClassID);
2599 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2600 TmpRegNum = RegOpNum;
2602 // At this point we need AT to perform the expansions and we exit if it is
2604 TmpRegNum = getATReg(IDLoc);
2609 emitRX(Mips::LUi, TmpRegNum,
2610 isImmOpnd ? MCOperand::createImm(HiOffset)
2611 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2612 IDLoc, Instructions);
2613 // Add temp register to base.
2614 if (BaseRegNum != Mips::ZERO)
2615 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2616 // And finally, create original instruction with low part
2617 // of offset and new base.
2618 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2620 ? MCOperand::createImm(LoOffset)
2621 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2622 IDLoc, Instructions);
2626 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2627 SmallVectorImpl<MCInst> &Instructions) {
2628 unsigned OpNum = Inst.getNumOperands();
2629 unsigned Opcode = Inst.getOpcode();
2630 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2632 assert (Inst.getOperand(OpNum - 1).isImm() &&
2633 Inst.getOperand(OpNum - 2).isReg() &&
2634 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2636 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2637 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2638 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2639 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2640 // It can be implemented as SWM16 or LWM16 instruction.
2641 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2643 Inst.setOpcode(NewOpcode);
2644 Instructions.push_back(Inst);
2648 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2649 SmallVectorImpl<MCInst> &Instructions) {
2650 bool EmittedNoMacroWarning = false;
2651 unsigned PseudoOpcode = Inst.getOpcode();
2652 unsigned SrcReg = Inst.getOperand(0).getReg();
2653 const MCOperand &TrgOp = Inst.getOperand(1);
2654 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2656 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2657 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2661 TrgReg = TrgOp.getReg();
2662 else if (TrgOp.isImm()) {
2663 warnIfNoMacro(IDLoc);
2664 EmittedNoMacroWarning = true;
2666 TrgReg = getATReg(IDLoc);
2670 switch(PseudoOpcode) {
2672 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2673 case Mips::BLTImmMacro:
2674 PseudoOpcode = Mips::BLT;
2676 case Mips::BLEImmMacro:
2677 PseudoOpcode = Mips::BLE;
2679 case Mips::BGEImmMacro:
2680 PseudoOpcode = Mips::BGE;
2682 case Mips::BGTImmMacro:
2683 PseudoOpcode = Mips::BGT;
2685 case Mips::BLTUImmMacro:
2686 PseudoOpcode = Mips::BLTU;
2688 case Mips::BLEUImmMacro:
2689 PseudoOpcode = Mips::BLEU;
2691 case Mips::BGEUImmMacro:
2692 PseudoOpcode = Mips::BGEU;
2694 case Mips::BGTUImmMacro:
2695 PseudoOpcode = Mips::BGTU;
2697 case Mips::BLTLImmMacro:
2698 PseudoOpcode = Mips::BLTL;
2700 case Mips::BLELImmMacro:
2701 PseudoOpcode = Mips::BLEL;
2703 case Mips::BGELImmMacro:
2704 PseudoOpcode = Mips::BGEL;
2706 case Mips::BGTLImmMacro:
2707 PseudoOpcode = Mips::BGTL;
2709 case Mips::BLTULImmMacro:
2710 PseudoOpcode = Mips::BLTUL;
2712 case Mips::BLEULImmMacro:
2713 PseudoOpcode = Mips::BLEUL;
2715 case Mips::BGEULImmMacro:
2716 PseudoOpcode = Mips::BGEUL;
2718 case Mips::BGTULImmMacro:
2719 PseudoOpcode = Mips::BGTUL;
2723 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2724 false, IDLoc, Instructions))
2728 switch (PseudoOpcode) {
2733 AcceptsEquality = false;
2734 ReverseOrderSLT = false;
2735 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2736 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2737 ZeroSrcOpcode = Mips::BGTZ;
2738 ZeroTrgOpcode = Mips::BLTZ;
2744 AcceptsEquality = true;
2745 ReverseOrderSLT = true;
2746 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2747 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2748 ZeroSrcOpcode = Mips::BGEZ;
2749 ZeroTrgOpcode = Mips::BLEZ;
2755 AcceptsEquality = true;
2756 ReverseOrderSLT = false;
2757 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2758 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2759 ZeroSrcOpcode = Mips::BLEZ;
2760 ZeroTrgOpcode = Mips::BGEZ;
2766 AcceptsEquality = false;
2767 ReverseOrderSLT = true;
2768 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2769 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2770 ZeroSrcOpcode = Mips::BLTZ;
2771 ZeroTrgOpcode = Mips::BGTZ;
2774 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2777 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2778 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2779 if (IsSrcRegZero && IsTrgRegZero) {
2780 // FIXME: All of these Opcode-specific if's are needed for compatibility
2781 // with GAS' behaviour. However, they may not generate the most efficient
2782 // code in some circumstances.
2783 if (PseudoOpcode == Mips::BLT) {
2784 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2788 if (PseudoOpcode == Mips::BLE) {
2789 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2791 Warning(IDLoc, "branch is always taken");
2794 if (PseudoOpcode == Mips::BGE) {
2795 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2797 Warning(IDLoc, "branch is always taken");
2800 if (PseudoOpcode == Mips::BGT) {
2801 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2805 if (PseudoOpcode == Mips::BGTU) {
2806 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2807 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2810 if (AcceptsEquality) {
2811 // If both registers are $0 and the pseudo-branch accepts equality, it
2812 // will always be taken, so we emit an unconditional branch.
2813 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2814 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2815 Warning(IDLoc, "branch is always taken");
2818 // If both registers are $0 and the pseudo-branch does not accept
2819 // equality, it will never be taken, so we don't have to emit anything.
2822 if (IsSrcRegZero || IsTrgRegZero) {
2823 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2824 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2825 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2826 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2827 // the pseudo-branch will never be taken, so we don't emit anything.
2828 // This only applies to unsigned pseudo-branches.
2831 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2832 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2833 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2834 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2835 // the pseudo-branch will always be taken, so we emit an unconditional
2837 // This only applies to unsigned pseudo-branches.
2838 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2839 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2840 Warning(IDLoc, "branch is always taken");
2844 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2845 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2846 // the pseudo-branch will be taken only when the non-zero register is
2847 // different from 0, so we emit a BNEZ.
2849 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2850 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2851 // the pseudo-branch will be taken only when the non-zero register is
2852 // equal to 0, so we emit a BEQZ.
2854 // Because only BLEU and BGEU branch on equality, we can use the
2855 // AcceptsEquality variable to decide when to emit the BEQZ.
2856 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2857 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2858 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2861 // If we have a signed pseudo-branch and one of the registers is $0,
2862 // we can use an appropriate compare-to-zero branch. We select which one
2863 // to use in the switch statement above.
2864 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2865 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2866 IDLoc, Instructions);
2870 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2871 // expansions. If it is not available, we return.
2872 unsigned ATRegNum = getATReg(IDLoc);
2876 if (!EmittedNoMacroWarning)
2877 warnIfNoMacro(IDLoc);
2879 // SLT fits well with 2 of our 4 pseudo-branches:
2880 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2881 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2882 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2883 // This is accomplished by using a BNEZ with the result of the SLT.
2885 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2886 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2887 // Because only BGE and BLE branch on equality, we can use the
2888 // AcceptsEquality variable to decide when to emit the BEQZ.
2889 // Note that the order of the SLT arguments doesn't change between
2892 // The same applies to the unsigned variants, except that SLTu is used
2894 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2895 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2896 IDLoc, Instructions);
2898 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2899 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2900 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2905 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2906 SmallVectorImpl<MCInst> &Instructions,
2907 const bool IsMips64, const bool Signed) {
2908 if (hasMips32r6()) {
2909 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2913 warnIfNoMacro(IDLoc);
2915 const MCOperand &RsRegOp = Inst.getOperand(0);
2916 assert(RsRegOp.isReg() && "expected register operand kind");
2917 unsigned RsReg = RsRegOp.getReg();
2919 const MCOperand &RtRegOp = Inst.getOperand(1);
2920 assert(RtRegOp.isReg() && "expected register operand kind");
2921 unsigned RtReg = RtRegOp.getReg();
2926 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2927 ZeroReg = Mips::ZERO_64;
2929 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2930 ZeroReg = Mips::ZERO;
2933 bool UseTraps = useTraps();
2935 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2936 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2937 Warning(IDLoc, "dividing zero by zero");
2939 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2941 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2945 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2949 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2954 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2955 Warning(IDLoc, "division by zero");
2958 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2962 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2967 // FIXME: The values for these two BranchTarget variables may be different in
2968 // micromips. These magic numbers need to be removed.
2969 unsigned BranchTargetNoTraps;
2970 unsigned BranchTarget;
2973 BranchTarget = IsMips64 ? 12 : 8;
2974 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2976 BranchTarget = IsMips64 ? 20 : 16;
2977 BranchTargetNoTraps = 8;
2978 // Branch to the li instruction.
2979 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2983 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2986 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2989 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2993 unsigned ATReg = getATReg(IDLoc);
2997 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2999 // Branch to the mflo instruction.
3000 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3001 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
3002 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
3004 // Branch to the mflo instruction.
3005 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3006 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
3010 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
3012 // Branch to the mflo instruction.
3013 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
3014 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
3015 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
3017 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3021 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
3022 SmallVectorImpl<MCInst> &Instructions) {
3023 if (hasMips32r6() || hasMips64r6()) {
3024 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3028 warnIfNoMacro(IDLoc);
3030 const MCOperand &DstRegOp = Inst.getOperand(0);
3031 assert(DstRegOp.isReg() && "expected register operand kind");
3033 const MCOperand &SrcRegOp = Inst.getOperand(1);
3034 assert(SrcRegOp.isReg() && "expected register operand kind");
3036 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3037 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3039 unsigned DstReg = DstRegOp.getReg();
3040 unsigned SrcReg = SrcRegOp.getReg();
3041 int64_t OffsetValue = OffsetImmOp.getImm();
3043 // NOTE: We always need AT for ULHU, as it is always used as the source
3044 // register for one of the LBu's.
3045 unsigned ATReg = getATReg(IDLoc);
3049 // When the value of offset+1 does not fit in 16 bits, we have to load the
3050 // offset in AT, (D)ADDu the original source register (if there was one), and
3051 // then use AT as the source register for the 2 generated LBu's.
3052 bool LoadedOffsetInAT = false;
3053 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3054 LoadedOffsetInAT = true;
3056 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3057 true, IDLoc, Instructions))
3060 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3061 // because it will make our output more similar to GAS'. For example,
3062 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3063 // instead of just an "ori $1, $9, 32768".
3064 // NOTE: If there is no source register specified in the ULHU, the parser
3065 // will interpret it as $0.
3066 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3067 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3070 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3071 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3072 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3074 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3076 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3077 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3079 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3080 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3083 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3085 emitRRI(Mips::LBu, FirstLbuDstReg, LbuSrcReg, FirstLbuOffset, IDLoc,
3088 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3091 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3093 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3098 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3099 SmallVectorImpl<MCInst> &Instructions) {
3100 if (hasMips32r6() || hasMips64r6()) {
3101 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3105 const MCOperand &DstRegOp = Inst.getOperand(0);
3106 assert(DstRegOp.isReg() && "expected register operand kind");
3108 const MCOperand &SrcRegOp = Inst.getOperand(1);
3109 assert(SrcRegOp.isReg() && "expected register operand kind");
3111 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3112 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3114 unsigned SrcReg = SrcRegOp.getReg();
3115 int64_t OffsetValue = OffsetImmOp.getImm();
3118 // When the value of offset+3 does not fit in 16 bits, we have to load the
3119 // offset in AT, (D)ADDu the original source register (if there was one), and
3120 // then use AT as the source register for the generated LWL and LWR.
3121 bool LoadedOffsetInAT = false;
3122 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3123 ATReg = getATReg(IDLoc);
3126 LoadedOffsetInAT = true;
3128 warnIfNoMacro(IDLoc);
3130 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3131 true, IDLoc, Instructions))
3134 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3135 // because it will make our output more similar to GAS'. For example,
3136 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3137 // instead of just an "ori $1, $9, 32768".
3138 // NOTE: If there is no source register specified in the ULW, the parser
3139 // will interpret it as $0.
3140 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3141 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3144 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3145 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3147 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3148 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3150 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3151 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3154 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3157 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3163 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3164 SmallVectorImpl<MCInst> &Instructions) {
3166 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3167 assert (Inst.getOperand(0).isReg() &&
3168 Inst.getOperand(1).isReg() &&
3169 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3171 unsigned ATReg = Mips::NoRegister;
3172 unsigned FinalDstReg = Mips::NoRegister;
3173 unsigned DstReg = Inst.getOperand(0).getReg();
3174 unsigned SrcReg = Inst.getOperand(1).getReg();
3175 int64_t ImmValue = Inst.getOperand(2).getImm();
3177 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3179 unsigned FinalOpcode = Inst.getOpcode();
3181 if (DstReg == SrcReg) {
3182 ATReg = getATReg(Inst.getLoc());
3185 FinalDstReg = DstReg;
3189 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3190 switch (FinalOpcode) {
3192 llvm_unreachable("unimplemented expansion");
3194 FinalOpcode = Mips::ADD;
3197 FinalOpcode = Mips::ADDu;
3200 FinalOpcode = Mips::AND;
3202 case (Mips::NORImm):
3203 FinalOpcode = Mips::NOR;
3206 FinalOpcode = Mips::OR;
3209 FinalOpcode = Mips::SLT;
3212 FinalOpcode = Mips::SLTu;
3215 FinalOpcode = Mips::XOR;
3219 if (FinalDstReg == Mips::NoRegister)
3220 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3222 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3229 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3230 SmallVectorImpl<MCInst> &Instructions) {
3231 if (hasShortDelaySlot)
3232 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3234 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3237 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3238 unsigned TrgReg, bool Is64Bit,
3239 SmallVectorImpl<MCInst> &Instructions) {
3240 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3244 void MipsAsmParser::createCpRestoreMemOp(
3245 bool IsLoad, int StackOffset, SMLoc IDLoc,
3246 SmallVectorImpl<MCInst> &Instructions) {
3247 // If the offset can not fit into 16 bits, we need to expand.
3248 if (!isInt<16>(StackOffset)) {
3250 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3251 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3252 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3253 MemInst.addOperand(MCOperand::createImm(StackOffset));
3254 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3258 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3262 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3263 // As described by the Mips32r2 spec, the registers Rd and Rs for
3264 // jalr.hb must be different.
3265 unsigned Opcode = Inst.getOpcode();
3267 if (Opcode == Mips::JALR_HB &&
3268 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3269 return Match_RequiresDifferentSrcAndDst;
3271 return Match_Success;
3274 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3275 OperandVector &Operands,
3277 uint64_t &ErrorInfo,
3278 bool MatchingInlineAsm) {
3281 SmallVector<MCInst, 8> Instructions;
3282 unsigned MatchResult =
3283 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3285 switch (MatchResult) {
3286 case Match_Success: {
3287 if (processInstruction(Inst, IDLoc, Instructions))
3289 for (unsigned i = 0; i < Instructions.size(); i++)
3290 Out.EmitInstruction(Instructions[i], STI);
3293 case Match_MissingFeature:
3294 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3296 case Match_InvalidOperand: {
3297 SMLoc ErrorLoc = IDLoc;
3298 if (ErrorInfo != ~0ULL) {
3299 if (ErrorInfo >= Operands.size())
3300 return Error(IDLoc, "too few operands for instruction");
3302 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3303 if (ErrorLoc == SMLoc())
3307 return Error(ErrorLoc, "invalid operand for instruction");
3309 case Match_MnemonicFail:
3310 return Error(IDLoc, "invalid instruction");
3311 case Match_RequiresDifferentSrcAndDst:
3312 return Error(IDLoc, "source and destination must be different");
3315 llvm_unreachable("Implement any new match types added!");
3318 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3319 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3320 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3321 ") without \".set noat\"");
3324 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3325 if (!AssemblerOptions.back()->isMacro())
3326 Warning(Loc, "macro instruction expanded into multiple instructions");
3330 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3331 SMRange Range, bool ShowColors) {
3332 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3333 Range, SMFixIt(Range, FixMsg),
3337 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3340 CC = StringSwitch<unsigned>(Name)
3376 if (!(isABI_N32() || isABI_N64()))
3379 if (12 <= CC && CC <= 15) {
3380 // Name is one of t4-t7
3381 AsmToken RegTok = getLexer().peekTok();
3382 SMRange RegRange = RegTok.getLocRange();
3384 StringRef FixedName = StringSwitch<StringRef>(Name)
3390 assert(FixedName != "" && "Register name is not one of t4-t7.");
3392 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3393 "Did you mean $" + FixedName + "?", RegRange);
3396 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3397 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3398 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3399 if (8 <= CC && CC <= 11)
3403 CC = StringSwitch<unsigned>(Name)
3415 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3418 CC = StringSwitch<unsigned>(Name)
3419 .Case("hwr_cpunum", 0)
3420 .Case("hwr_synci_step", 1)
3422 .Case("hwr_ccres", 3)
3423 .Case("hwr_ulr", 29)
3429 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3431 if (Name[0] == 'f') {
3432 StringRef NumString = Name.substr(1);
3434 if (NumString.getAsInteger(10, IntVal))
3435 return -1; // This is not an integer.
3436 if (IntVal > 31) // Maximum index for fpu register.
3443 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3445 if (Name.startswith("fcc")) {
3446 StringRef NumString = Name.substr(3);
3448 if (NumString.getAsInteger(10, IntVal))
3449 return -1; // This is not an integer.
3450 if (IntVal > 7) // There are only 8 fcc registers.
3457 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3459 if (Name.startswith("ac")) {
3460 StringRef NumString = Name.substr(2);
3462 if (NumString.getAsInteger(10, IntVal))
3463 return -1; // This is not an integer.
3464 if (IntVal > 3) // There are only 3 acc registers.
3471 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3474 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3483 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3486 CC = StringSwitch<unsigned>(Name)
3489 .Case("msaaccess", 2)
3491 .Case("msamodify", 4)
3492 .Case("msarequest", 5)
3494 .Case("msaunmap", 7)
3500 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3501 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3503 reportParseError(Loc,
3504 "pseudo-instruction requires $at, which is not available");
3507 unsigned AT = getReg(
3508 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3512 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3513 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3516 unsigned MipsAsmParser::getGPR(int RegNo) {
3517 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3521 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3523 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3526 return getReg(RegClass, RegNum);
3529 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3530 MCAsmParser &Parser = getParser();
3531 DEBUG(dbgs() << "parseOperand\n");
3533 // Check if the current operand has a custom associated parser, if so, try to
3534 // custom parse the operand, or fallback to the general approach.
3535 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3536 if (ResTy == MatchOperand_Success)
3538 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3539 // there was a match, but an error occurred, in which case, just return that
3540 // the operand parsing failed.
3541 if (ResTy == MatchOperand_ParseFail)
3544 DEBUG(dbgs() << ".. Generic Parser\n");
3546 switch (getLexer().getKind()) {
3548 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3550 case AsmToken::Dollar: {
3551 // Parse the register.
3552 SMLoc S = Parser.getTok().getLoc();
3554 // Almost all registers have been parsed by custom parsers. There is only
3555 // one exception to this. $zero (and it's alias $0) will reach this point
3556 // for div, divu, and similar instructions because it is not an operand
3557 // to the instruction definition but an explicit register. Special case
3558 // this situation for now.
3559 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3562 // Maybe it is a symbol reference.
3563 StringRef Identifier;
3564 if (Parser.parseIdentifier(Identifier))
3567 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3568 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3569 // Otherwise create a symbol reference.
3571 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3573 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3576 // Else drop to expression parsing.
3577 case AsmToken::LParen:
3578 case AsmToken::Minus:
3579 case AsmToken::Plus:
3580 case AsmToken::Integer:
3581 case AsmToken::Tilde:
3582 case AsmToken::String: {
3583 DEBUG(dbgs() << ".. generic integer\n");
3584 OperandMatchResultTy ResTy = parseImm(Operands);
3585 return ResTy != MatchOperand_Success;
3587 case AsmToken::Percent: {
3588 // It is a symbol reference or constant expression.
3589 const MCExpr *IdVal;
3590 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3591 if (parseRelocOperand(IdVal))
3594 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3596 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3598 } // case AsmToken::Percent
3599 } // switch(getLexer().getKind())
3603 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3604 StringRef RelocStr) {
3606 // Check the type of the expression.
3607 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3608 // It's a constant, evaluate reloc value.
3610 switch (getVariantKind(RelocStr)) {
3611 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3612 // Get the 1st 16-bits.
3613 Val = MCE->getValue() & 0xffff;
3615 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3616 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3617 // 16 bits being negative.
3618 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3620 case MCSymbolRefExpr::VK_Mips_HIGHER:
3621 // Get the 3rd 16-bits.
3622 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3624 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3625 // Get the 4th 16-bits.
3626 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3629 report_fatal_error("unsupported reloc value");
3631 return MCConstantExpr::create(Val, getContext());
3634 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3635 // It's a symbol, create a symbolic expression from the symbol.
3636 const MCSymbol *Symbol = &MSRE->getSymbol();
3637 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3638 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3642 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3643 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3645 // Try to create target expression.
3646 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3647 return MipsMCExpr::create(VK, Expr, getContext());
3649 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3650 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3651 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3655 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3656 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3657 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3660 // Just return the original expression.
3664 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3666 switch (Expr->getKind()) {
3667 case MCExpr::Constant:
3669 case MCExpr::SymbolRef:
3670 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3671 case MCExpr::Binary:
3672 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3673 if (!isEvaluated(BE->getLHS()))
3675 return isEvaluated(BE->getRHS());
3678 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3679 case MCExpr::Target:
3685 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3686 MCAsmParser &Parser = getParser();
3687 Parser.Lex(); // Eat the % token.
3688 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3689 if (Tok.isNot(AsmToken::Identifier))
3692 std::string Str = Tok.getIdentifier();
3694 Parser.Lex(); // Eat the identifier.
3695 // Now make an expression from the rest of the operand.
3696 const MCExpr *IdVal;
3699 if (getLexer().getKind() == AsmToken::LParen) {
3701 Parser.Lex(); // Eat the '(' token.
3702 if (getLexer().getKind() == AsmToken::Percent) {
3703 Parser.Lex(); // Eat the % token.
3704 const AsmToken &nextTok = Parser.getTok();
3705 if (nextTok.isNot(AsmToken::Identifier))
3708 Str += nextTok.getIdentifier();
3709 Parser.Lex(); // Eat the identifier.
3710 if (getLexer().getKind() != AsmToken::LParen)
3715 if (getParser().parseParenExpression(IdVal, EndLoc))
3718 while (getLexer().getKind() == AsmToken::RParen)
3719 Parser.Lex(); // Eat the ')' token.
3722 return true; // Parenthesis must follow the relocation operand.
3724 Res = evaluateRelocExpr(IdVal, Str);
3728 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3730 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3731 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3732 if (ResTy == MatchOperand_Success) {
3733 assert(Operands.size() == 1);
3734 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3735 StartLoc = Operand.getStartLoc();
3736 EndLoc = Operand.getEndLoc();
3738 // AFAIK, we only support numeric registers and named GPR's in CFI
3740 // Don't worry about eating tokens before failing. Using an unrecognised
3741 // register is a parse error.
3742 if (Operand.isGPRAsmReg()) {
3743 // Resolve to GPR32 or GPR64 appropriately.
3744 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3747 return (RegNo == (unsigned)-1);
3750 assert(Operands.size() == 0);
3751 return (RegNo == (unsigned)-1);
3754 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3755 MCAsmParser &Parser = getParser();
3758 unsigned NumOfLParen = 0;
3760 while (getLexer().getKind() == AsmToken::LParen) {
3765 switch (getLexer().getKind()) {
3768 case AsmToken::Identifier:
3769 case AsmToken::LParen:
3770 case AsmToken::Integer:
3771 case AsmToken::Minus:
3772 case AsmToken::Plus:
3774 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3776 Result = (getParser().parseExpression(Res));
3777 while (getLexer().getKind() == AsmToken::RParen)
3780 case AsmToken::Percent:
3781 Result = parseRelocOperand(Res);
3786 MipsAsmParser::OperandMatchResultTy
3787 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3788 MCAsmParser &Parser = getParser();
3789 DEBUG(dbgs() << "parseMemOperand\n");
3790 const MCExpr *IdVal = nullptr;
3792 bool isParenExpr = false;
3793 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3794 // First operand is the offset.
3795 S = Parser.getTok().getLoc();
3797 if (getLexer().getKind() == AsmToken::LParen) {
3802 if (getLexer().getKind() != AsmToken::Dollar) {
3803 if (parseMemOffset(IdVal, isParenExpr))
3804 return MatchOperand_ParseFail;
3806 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3807 if (Tok.isNot(AsmToken::LParen)) {
3808 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3809 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3811 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3812 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3813 return MatchOperand_Success;
3815 if (Tok.is(AsmToken::EndOfStatement)) {
3817 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3819 // Zero register assumed, add a memory operand with ZERO as its base.
3820 // "Base" will be managed by k_Memory.
3821 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3824 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3825 return MatchOperand_Success;
3827 Error(Parser.getTok().getLoc(), "'(' expected");
3828 return MatchOperand_ParseFail;
3831 Parser.Lex(); // Eat the '(' token.
3834 Res = parseAnyRegister(Operands);
3835 if (Res != MatchOperand_Success)
3838 if (Parser.getTok().isNot(AsmToken::RParen)) {
3839 Error(Parser.getTok().getLoc(), "')' expected");
3840 return MatchOperand_ParseFail;
3843 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3845 Parser.Lex(); // Eat the ')' token.
3848 IdVal = MCConstantExpr::create(0, getContext());
3850 // Replace the register operand with the memory operand.
3851 std::unique_ptr<MipsOperand> op(
3852 static_cast<MipsOperand *>(Operands.back().release()));
3853 // Remove the register from the operands.
3854 // "op" will be managed by k_Memory.
3855 Operands.pop_back();
3856 // Add the memory operand.
3857 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3859 if (IdVal->evaluateAsAbsolute(Imm))
3860 IdVal = MCConstantExpr::create(Imm, getContext());
3861 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3862 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3866 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3867 return MatchOperand_Success;
3870 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3871 MCAsmParser &Parser = getParser();
3872 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3874 SMLoc S = Parser.getTok().getLoc();
3876 if (Sym->isVariable())
3877 Expr = Sym->getVariableValue();
3880 if (Expr->getKind() == MCExpr::SymbolRef) {
3881 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3882 StringRef DefSymbol = Ref->getSymbol().getName();
3883 if (DefSymbol.startswith("$")) {
3884 OperandMatchResultTy ResTy =
3885 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3886 if (ResTy == MatchOperand_Success) {
3889 } else if (ResTy == MatchOperand_ParseFail)
3890 llvm_unreachable("Should never ParseFail");
3893 } else if (Expr->getKind() == MCExpr::Constant) {
3895 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3897 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3904 MipsAsmParser::OperandMatchResultTy
3905 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3906 StringRef Identifier,
3908 int Index = matchCPURegisterName(Identifier);
3910 Operands.push_back(MipsOperand::createGPRReg(
3911 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3912 return MatchOperand_Success;
3915 Index = matchHWRegsRegisterName(Identifier);
3917 Operands.push_back(MipsOperand::createHWRegsReg(
3918 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3919 return MatchOperand_Success;
3922 Index = matchFPURegisterName(Identifier);
3924 Operands.push_back(MipsOperand::createFGRReg(
3925 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3926 return MatchOperand_Success;
3929 Index = matchFCCRegisterName(Identifier);
3931 Operands.push_back(MipsOperand::createFCCReg(
3932 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3933 return MatchOperand_Success;
3936 Index = matchACRegisterName(Identifier);
3938 Operands.push_back(MipsOperand::createACCReg(
3939 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3940 return MatchOperand_Success;
3943 Index = matchMSA128RegisterName(Identifier);
3945 Operands.push_back(MipsOperand::createMSA128Reg(
3946 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3947 return MatchOperand_Success;
3950 Index = matchMSA128CtrlRegisterName(Identifier);
3952 Operands.push_back(MipsOperand::createMSACtrlReg(
3953 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3954 return MatchOperand_Success;
3957 return MatchOperand_NoMatch;
3960 MipsAsmParser::OperandMatchResultTy
3961 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3962 MCAsmParser &Parser = getParser();
3963 auto Token = Parser.getLexer().peekTok(false);
3965 if (Token.is(AsmToken::Identifier)) {
3966 DEBUG(dbgs() << ".. identifier\n");
3967 StringRef Identifier = Token.getIdentifier();
3968 OperandMatchResultTy ResTy =
3969 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3971 } else if (Token.is(AsmToken::Integer)) {
3972 DEBUG(dbgs() << ".. integer\n");
3973 Operands.push_back(MipsOperand::createNumericReg(
3974 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3976 return MatchOperand_Success;
3979 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3981 return MatchOperand_NoMatch;
3984 MipsAsmParser::OperandMatchResultTy
3985 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3986 MCAsmParser &Parser = getParser();
3987 DEBUG(dbgs() << "parseAnyRegister\n");
3989 auto Token = Parser.getTok();
3991 SMLoc S = Token.getLoc();
3993 if (Token.isNot(AsmToken::Dollar)) {
3994 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3995 if (Token.is(AsmToken::Identifier)) {
3996 if (searchSymbolAlias(Operands))
3997 return MatchOperand_Success;
3999 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4000 return MatchOperand_NoMatch;
4002 DEBUG(dbgs() << ".. $\n");
4004 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4005 if (ResTy == MatchOperand_Success) {
4007 Parser.Lex(); // identifier
4012 MipsAsmParser::OperandMatchResultTy
4013 MipsAsmParser::parseImm(OperandVector &Operands) {
4014 MCAsmParser &Parser = getParser();
4015 switch (getLexer().getKind()) {
4017 return MatchOperand_NoMatch;
4018 case AsmToken::LParen:
4019 case AsmToken::Minus:
4020 case AsmToken::Plus:
4021 case AsmToken::Integer:
4022 case AsmToken::Tilde:
4023 case AsmToken::String:
4027 const MCExpr *IdVal;
4028 SMLoc S = Parser.getTok().getLoc();
4029 if (getParser().parseExpression(IdVal))
4030 return MatchOperand_ParseFail;
4032 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4033 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4034 return MatchOperand_Success;
4037 MipsAsmParser::OperandMatchResultTy
4038 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4039 MCAsmParser &Parser = getParser();
4040 DEBUG(dbgs() << "parseJumpTarget\n");
4042 SMLoc S = getLexer().getLoc();
4044 // Integers and expressions are acceptable
4045 OperandMatchResultTy ResTy = parseImm(Operands);
4046 if (ResTy != MatchOperand_NoMatch)
4049 // Registers are a valid target and have priority over symbols.
4050 ResTy = parseAnyRegister(Operands);
4051 if (ResTy != MatchOperand_NoMatch)
4054 const MCExpr *Expr = nullptr;
4055 if (Parser.parseExpression(Expr)) {
4056 // We have no way of knowing if a symbol was consumed so we must ParseFail
4057 return MatchOperand_ParseFail;
4060 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4061 return MatchOperand_Success;
4064 MipsAsmParser::OperandMatchResultTy
4065 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4066 MCAsmParser &Parser = getParser();
4067 const MCExpr *IdVal;
4068 // If the first token is '$' we may have register operand.
4069 if (Parser.getTok().is(AsmToken::Dollar))
4070 return MatchOperand_NoMatch;
4071 SMLoc S = Parser.getTok().getLoc();
4072 if (getParser().parseExpression(IdVal))
4073 return MatchOperand_ParseFail;
4074 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4075 assert(MCE && "Unexpected MCExpr type.");
4076 int64_t Val = MCE->getValue();
4077 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4078 Operands.push_back(MipsOperand::CreateImm(
4079 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4080 return MatchOperand_Success;
4083 MipsAsmParser::OperandMatchResultTy
4084 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4085 MCAsmParser &Parser = getParser();
4086 switch (getLexer().getKind()) {
4088 return MatchOperand_NoMatch;
4089 case AsmToken::LParen:
4090 case AsmToken::Plus:
4091 case AsmToken::Minus:
4092 case AsmToken::Integer:
4097 SMLoc S = Parser.getTok().getLoc();
4099 if (getParser().parseExpression(Expr))
4100 return MatchOperand_ParseFail;
4103 if (!Expr->evaluateAsAbsolute(Val)) {
4104 Error(S, "expected immediate value");
4105 return MatchOperand_ParseFail;
4108 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4109 // and because the CPU always adds one to the immediate field, the allowed
4110 // range becomes 1..4. We'll only check the range here and will deal
4111 // with the addition/subtraction when actually decoding/encoding
4113 if (Val < 1 || Val > 4) {
4114 Error(S, "immediate not in range (1..4)");
4115 return MatchOperand_ParseFail;
4119 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4120 return MatchOperand_Success;
4123 MipsAsmParser::OperandMatchResultTy
4124 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4125 MCAsmParser &Parser = getParser();
4126 SmallVector<unsigned, 10> Regs;
4128 unsigned PrevReg = Mips::NoRegister;
4129 bool RegRange = false;
4130 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4132 if (Parser.getTok().isNot(AsmToken::Dollar))
4133 return MatchOperand_ParseFail;
4135 SMLoc S = Parser.getTok().getLoc();
4136 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4137 SMLoc E = getLexer().getLoc();
4138 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4139 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4141 // Remove last register operand because registers from register range
4142 // should be inserted first.
4143 if (RegNo == Mips::RA) {
4144 Regs.push_back(RegNo);
4146 unsigned TmpReg = PrevReg + 1;
4147 while (TmpReg <= RegNo) {
4148 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4149 Error(E, "invalid register operand");
4150 return MatchOperand_ParseFail;
4154 Regs.push_back(TmpReg++);
4160 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4161 (RegNo != Mips::RA)) {
4162 Error(E, "$16 or $31 expected");
4163 return MatchOperand_ParseFail;
4164 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4165 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4166 Error(E, "invalid register operand");
4167 return MatchOperand_ParseFail;
4168 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4169 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4170 Error(E, "consecutive register numbers expected");
4171 return MatchOperand_ParseFail;
4174 Regs.push_back(RegNo);
4177 if (Parser.getTok().is(AsmToken::Minus))
4180 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4181 !Parser.getTok().isNot(AsmToken::Comma)) {
4182 Error(E, "',' or '-' expected");
4183 return MatchOperand_ParseFail;
4186 Lex(); // Consume comma or minus
4187 if (Parser.getTok().isNot(AsmToken::Dollar))
4193 SMLoc E = Parser.getTok().getLoc();
4194 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4195 parseMemOperand(Operands);
4196 return MatchOperand_Success;
4199 MipsAsmParser::OperandMatchResultTy
4200 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4201 MCAsmParser &Parser = getParser();
4203 SMLoc S = Parser.getTok().getLoc();
4204 if (parseAnyRegister(Operands) != MatchOperand_Success)
4205 return MatchOperand_ParseFail;
4207 SMLoc E = Parser.getTok().getLoc();
4208 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4209 unsigned Reg = Op.getGPR32Reg();
4210 Operands.pop_back();
4211 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4212 return MatchOperand_Success;
4215 MipsAsmParser::OperandMatchResultTy
4216 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4217 MCAsmParser &Parser = getParser();
4218 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4219 SmallVector<unsigned, 10> Regs;
4221 if (Parser.getTok().isNot(AsmToken::Dollar))
4222 return MatchOperand_ParseFail;
4224 SMLoc S = Parser.getTok().getLoc();
4226 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4227 return MatchOperand_ParseFail;
4229 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4230 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4231 Regs.push_back(RegNo);
4233 SMLoc E = Parser.getTok().getLoc();
4234 if (Parser.getTok().isNot(AsmToken::Comma)) {
4235 Error(E, "',' expected");
4236 return MatchOperand_ParseFail;
4242 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4243 return MatchOperand_ParseFail;
4245 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4246 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4247 Regs.push_back(RegNo);
4249 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4251 return MatchOperand_Success;
4254 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4256 MCSymbolRefExpr::VariantKind VK =
4257 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4258 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4259 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4260 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4261 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4262 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4263 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4264 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4265 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4266 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4267 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4268 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4269 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4270 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4271 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4272 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4273 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4274 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4275 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4276 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4277 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4278 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4279 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4280 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4281 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4282 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4283 .Default(MCSymbolRefExpr::VK_None);
4285 assert(VK != MCSymbolRefExpr::VK_None);
4290 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4292 /// ::= '(', register, ')'
4293 /// handle it before we iterate so we don't get tripped up by the lack of
4295 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4296 MCAsmParser &Parser = getParser();
4297 if (getLexer().is(AsmToken::LParen)) {
4299 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4301 if (parseOperand(Operands, Name)) {
4302 SMLoc Loc = getLexer().getLoc();
4303 Parser.eatToEndOfStatement();
4304 return Error(Loc, "unexpected token in argument list");
4306 if (Parser.getTok().isNot(AsmToken::RParen)) {
4307 SMLoc Loc = getLexer().getLoc();
4308 Parser.eatToEndOfStatement();
4309 return Error(Loc, "unexpected token, expected ')'");
4312 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4318 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4319 /// either one of these.
4320 /// ::= '[', register, ']'
4321 /// ::= '[', integer, ']'
4322 /// handle it before we iterate so we don't get tripped up by the lack of
4324 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4325 OperandVector &Operands) {
4326 MCAsmParser &Parser = getParser();
4327 if (getLexer().is(AsmToken::LBrac)) {
4329 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4331 if (parseOperand(Operands, Name)) {
4332 SMLoc Loc = getLexer().getLoc();
4333 Parser.eatToEndOfStatement();
4334 return Error(Loc, "unexpected token in argument list");
4336 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4337 SMLoc Loc = getLexer().getLoc();
4338 Parser.eatToEndOfStatement();
4339 return Error(Loc, "unexpected token, expected ']'");
4342 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4348 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4349 SMLoc NameLoc, OperandVector &Operands) {
4350 MCAsmParser &Parser = getParser();
4351 DEBUG(dbgs() << "ParseInstruction\n");
4353 // We have reached first instruction, module directive are now forbidden.
4354 getTargetStreamer().forbidModuleDirective();
4356 // Check if we have valid mnemonic
4357 if (!mnemonicIsValid(Name, 0)) {
4358 Parser.eatToEndOfStatement();
4359 return Error(NameLoc, "unknown instruction");
4361 // First operand in MCInst is instruction mnemonic.
4362 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4364 // Read the remaining operands.
4365 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4366 // Read the first operand.
4367 if (parseOperand(Operands, Name)) {
4368 SMLoc Loc = getLexer().getLoc();
4369 Parser.eatToEndOfStatement();
4370 return Error(Loc, "unexpected token in argument list");
4372 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4374 // AFAIK, parenthesis suffixes are never on the first operand
4376 while (getLexer().is(AsmToken::Comma)) {
4377 Parser.Lex(); // Eat the comma.
4378 // Parse and remember the operand.
4379 if (parseOperand(Operands, Name)) {
4380 SMLoc Loc = getLexer().getLoc();
4381 Parser.eatToEndOfStatement();
4382 return Error(Loc, "unexpected token in argument list");
4384 // Parse bracket and parenthesis suffixes before we iterate
4385 if (getLexer().is(AsmToken::LBrac)) {
4386 if (parseBracketSuffix(Name, Operands))
4388 } else if (getLexer().is(AsmToken::LParen) &&
4389 parseParenSuffix(Name, Operands))
4393 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4394 SMLoc Loc = getLexer().getLoc();
4395 Parser.eatToEndOfStatement();
4396 return Error(Loc, "unexpected token in argument list");
4398 Parser.Lex(); // Consume the EndOfStatement.
4402 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4403 MCAsmParser &Parser = getParser();
4404 SMLoc Loc = getLexer().getLoc();
4405 Parser.eatToEndOfStatement();
4406 return Error(Loc, ErrorMsg);
4409 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4410 return Error(Loc, ErrorMsg);
4413 bool MipsAsmParser::parseSetNoAtDirective() {
4414 MCAsmParser &Parser = getParser();
4415 // Line should look like: ".set noat".
4417 // Set the $at register to $0.
4418 AssemblerOptions.back()->setATRegIndex(0);
4420 Parser.Lex(); // Eat "noat".
4422 // If this is not the end of the statement, report an error.
4423 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4424 reportParseError("unexpected token, expected end of statement");
4428 getTargetStreamer().emitDirectiveSetNoAt();
4429 Parser.Lex(); // Consume the EndOfStatement.
4433 bool MipsAsmParser::parseSetAtDirective() {
4434 // Line can be: ".set at", which sets $at to $1
4435 // or ".set at=$reg", which sets $at to $reg.
4436 MCAsmParser &Parser = getParser();
4437 Parser.Lex(); // Eat "at".
4439 if (getLexer().is(AsmToken::EndOfStatement)) {
4440 // No register was specified, so we set $at to $1.
4441 AssemblerOptions.back()->setATRegIndex(1);
4443 getTargetStreamer().emitDirectiveSetAt();
4444 Parser.Lex(); // Consume the EndOfStatement.
4448 if (getLexer().isNot(AsmToken::Equal)) {
4449 reportParseError("unexpected token, expected equals sign");
4452 Parser.Lex(); // Eat "=".
4454 if (getLexer().isNot(AsmToken::Dollar)) {
4455 if (getLexer().is(AsmToken::EndOfStatement)) {
4456 reportParseError("no register specified");
4459 reportParseError("unexpected token, expected dollar sign '$'");
4463 Parser.Lex(); // Eat "$".
4465 // Find out what "reg" is.
4467 const AsmToken &Reg = Parser.getTok();
4468 if (Reg.is(AsmToken::Identifier)) {
4469 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4470 } else if (Reg.is(AsmToken::Integer)) {
4471 AtRegNo = Reg.getIntVal();
4473 reportParseError("unexpected token, expected identifier or integer");
4477 // Check if $reg is a valid register. If it is, set $at to $reg.
4478 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4479 reportParseError("invalid register");
4482 Parser.Lex(); // Eat "reg".
4484 // If this is not the end of the statement, report an error.
4485 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4486 reportParseError("unexpected token, expected end of statement");
4490 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4492 Parser.Lex(); // Consume the EndOfStatement.
4496 bool MipsAsmParser::parseSetReorderDirective() {
4497 MCAsmParser &Parser = getParser();
4499 // If this is not the end of the statement, report an error.
4500 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4501 reportParseError("unexpected token, expected end of statement");
4504 AssemblerOptions.back()->setReorder();
4505 getTargetStreamer().emitDirectiveSetReorder();
4506 Parser.Lex(); // Consume the EndOfStatement.
4510 bool MipsAsmParser::parseSetNoReorderDirective() {
4511 MCAsmParser &Parser = getParser();
4513 // If this is not the end of the statement, report an error.
4514 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4515 reportParseError("unexpected token, expected end of statement");
4518 AssemblerOptions.back()->setNoReorder();
4519 getTargetStreamer().emitDirectiveSetNoReorder();
4520 Parser.Lex(); // Consume the EndOfStatement.
4524 bool MipsAsmParser::parseSetMacroDirective() {
4525 MCAsmParser &Parser = getParser();
4527 // If this is not the end of the statement, report an error.
4528 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4529 reportParseError("unexpected token, expected end of statement");
4532 AssemblerOptions.back()->setMacro();
4533 getTargetStreamer().emitDirectiveSetMacro();
4534 Parser.Lex(); // Consume the EndOfStatement.
4538 bool MipsAsmParser::parseSetNoMacroDirective() {
4539 MCAsmParser &Parser = getParser();
4541 // If this is not the end of the statement, report an error.
4542 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4543 reportParseError("unexpected token, expected end of statement");
4546 if (AssemblerOptions.back()->isReorder()) {
4547 reportParseError("`noreorder' must be set before `nomacro'");
4550 AssemblerOptions.back()->setNoMacro();
4551 getTargetStreamer().emitDirectiveSetNoMacro();
4552 Parser.Lex(); // Consume the EndOfStatement.
4556 bool MipsAsmParser::parseSetMsaDirective() {
4557 MCAsmParser &Parser = getParser();
4560 // If this is not the end of the statement, report an error.
4561 if (getLexer().isNot(AsmToken::EndOfStatement))
4562 return reportParseError("unexpected token, expected end of statement");
4564 setFeatureBits(Mips::FeatureMSA, "msa");
4565 getTargetStreamer().emitDirectiveSetMsa();
4569 bool MipsAsmParser::parseSetNoMsaDirective() {
4570 MCAsmParser &Parser = getParser();
4573 // If this is not the end of the statement, report an error.
4574 if (getLexer().isNot(AsmToken::EndOfStatement))
4575 return reportParseError("unexpected token, expected end of statement");
4577 clearFeatureBits(Mips::FeatureMSA, "msa");
4578 getTargetStreamer().emitDirectiveSetNoMsa();
4582 bool MipsAsmParser::parseSetNoDspDirective() {
4583 MCAsmParser &Parser = getParser();
4584 Parser.Lex(); // Eat "nodsp".
4586 // If this is not the end of the statement, report an error.
4587 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4588 reportParseError("unexpected token, expected end of statement");
4592 clearFeatureBits(Mips::FeatureDSP, "dsp");
4593 getTargetStreamer().emitDirectiveSetNoDsp();
4597 bool MipsAsmParser::parseSetMips16Directive() {
4598 MCAsmParser &Parser = getParser();
4599 Parser.Lex(); // Eat "mips16".
4601 // If this is not the end of the statement, report an error.
4602 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4603 reportParseError("unexpected token, expected end of statement");
4607 setFeatureBits(Mips::FeatureMips16, "mips16");
4608 getTargetStreamer().emitDirectiveSetMips16();
4609 Parser.Lex(); // Consume the EndOfStatement.
4613 bool MipsAsmParser::parseSetNoMips16Directive() {
4614 MCAsmParser &Parser = getParser();
4615 Parser.Lex(); // Eat "nomips16".
4617 // If this is not the end of the statement, report an error.
4618 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4619 reportParseError("unexpected token, expected end of statement");
4623 clearFeatureBits(Mips::FeatureMips16, "mips16");
4624 getTargetStreamer().emitDirectiveSetNoMips16();
4625 Parser.Lex(); // Consume the EndOfStatement.
4629 bool MipsAsmParser::parseSetFpDirective() {
4630 MCAsmParser &Parser = getParser();
4631 MipsABIFlagsSection::FpABIKind FpAbiVal;
4632 // Line can be: .set fp=32
4635 Parser.Lex(); // Eat fp token
4636 AsmToken Tok = Parser.getTok();
4637 if (Tok.isNot(AsmToken::Equal)) {
4638 reportParseError("unexpected token, expected equals sign '='");
4641 Parser.Lex(); // Eat '=' token.
4642 Tok = Parser.getTok();
4644 if (!parseFpABIValue(FpAbiVal, ".set"))
4647 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4648 reportParseError("unexpected token, expected end of statement");
4651 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4652 Parser.Lex(); // Consume the EndOfStatement.
4656 bool MipsAsmParser::parseSetOddSPRegDirective() {
4657 MCAsmParser &Parser = getParser();
4659 Parser.Lex(); // Eat "oddspreg".
4660 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4661 reportParseError("unexpected token, expected end of statement");
4665 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4666 getTargetStreamer().emitDirectiveSetOddSPReg();
4670 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4671 MCAsmParser &Parser = getParser();
4673 Parser.Lex(); // Eat "nooddspreg".
4674 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4675 reportParseError("unexpected token, expected end of statement");
4679 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4680 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4684 bool MipsAsmParser::parseSetPopDirective() {
4685 MCAsmParser &Parser = getParser();
4686 SMLoc Loc = getLexer().getLoc();
4689 if (getLexer().isNot(AsmToken::EndOfStatement))
4690 return reportParseError("unexpected token, expected end of statement");
4692 // Always keep an element on the options "stack" to prevent the user
4693 // from changing the initial options. This is how we remember them.
4694 if (AssemblerOptions.size() == 2)
4695 return reportParseError(Loc, ".set pop with no .set push");
4697 AssemblerOptions.pop_back();
4698 setAvailableFeatures(
4699 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4700 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4702 getTargetStreamer().emitDirectiveSetPop();
4706 bool MipsAsmParser::parseSetPushDirective() {
4707 MCAsmParser &Parser = getParser();
4709 if (getLexer().isNot(AsmToken::EndOfStatement))
4710 return reportParseError("unexpected token, expected end of statement");
4712 // Create a copy of the current assembler options environment and push it.
4713 AssemblerOptions.push_back(
4714 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4716 getTargetStreamer().emitDirectiveSetPush();
4720 bool MipsAsmParser::parseSetSoftFloatDirective() {
4721 MCAsmParser &Parser = getParser();
4723 if (getLexer().isNot(AsmToken::EndOfStatement))
4724 return reportParseError("unexpected token, expected end of statement");
4726 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4727 getTargetStreamer().emitDirectiveSetSoftFloat();
4731 bool MipsAsmParser::parseSetHardFloatDirective() {
4732 MCAsmParser &Parser = getParser();
4734 if (getLexer().isNot(AsmToken::EndOfStatement))
4735 return reportParseError("unexpected token, expected end of statement");
4737 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4738 getTargetStreamer().emitDirectiveSetHardFloat();
4742 bool MipsAsmParser::parseSetAssignment() {
4744 const MCExpr *Value;
4745 MCAsmParser &Parser = getParser();
4747 if (Parser.parseIdentifier(Name))
4748 reportParseError("expected identifier after .set");
4750 if (getLexer().isNot(AsmToken::Comma))
4751 return reportParseError("unexpected token, expected comma");
4754 if (Parser.parseExpression(Value))
4755 return reportParseError("expected valid expression after comma");
4757 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4758 Sym->setVariableValue(Value);
4763 bool MipsAsmParser::parseSetMips0Directive() {
4764 MCAsmParser &Parser = getParser();
4766 if (getLexer().isNot(AsmToken::EndOfStatement))
4767 return reportParseError("unexpected token, expected end of statement");
4769 // Reset assembler options to their initial values.
4770 setAvailableFeatures(
4771 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4772 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4773 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4775 getTargetStreamer().emitDirectiveSetMips0();
4779 bool MipsAsmParser::parseSetArchDirective() {
4780 MCAsmParser &Parser = getParser();
4782 if (getLexer().isNot(AsmToken::Equal))
4783 return reportParseError("unexpected token, expected equals sign");
4787 if (Parser.parseIdentifier(Arch))
4788 return reportParseError("expected arch identifier");
4790 StringRef ArchFeatureName =
4791 StringSwitch<StringRef>(Arch)
4792 .Case("mips1", "mips1")
4793 .Case("mips2", "mips2")
4794 .Case("mips3", "mips3")
4795 .Case("mips4", "mips4")
4796 .Case("mips5", "mips5")
4797 .Case("mips32", "mips32")
4798 .Case("mips32r2", "mips32r2")
4799 .Case("mips32r3", "mips32r3")
4800 .Case("mips32r5", "mips32r5")
4801 .Case("mips32r6", "mips32r6")
4802 .Case("mips64", "mips64")
4803 .Case("mips64r2", "mips64r2")
4804 .Case("mips64r3", "mips64r3")
4805 .Case("mips64r5", "mips64r5")
4806 .Case("mips64r6", "mips64r6")
4807 .Case("cnmips", "cnmips")
4808 .Case("r4000", "mips3") // This is an implementation of Mips3.
4811 if (ArchFeatureName.empty())
4812 return reportParseError("unsupported architecture");
4814 selectArch(ArchFeatureName);
4815 getTargetStreamer().emitDirectiveSetArch(Arch);
4819 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4820 MCAsmParser &Parser = getParser();
4822 if (getLexer().isNot(AsmToken::EndOfStatement))
4823 return reportParseError("unexpected token, expected end of statement");
4827 llvm_unreachable("Unimplemented feature");
4828 case Mips::FeatureDSP:
4829 setFeatureBits(Mips::FeatureDSP, "dsp");
4830 getTargetStreamer().emitDirectiveSetDsp();
4832 case Mips::FeatureMicroMips:
4833 getTargetStreamer().emitDirectiveSetMicroMips();
4835 case Mips::FeatureMips1:
4836 selectArch("mips1");
4837 getTargetStreamer().emitDirectiveSetMips1();
4839 case Mips::FeatureMips2:
4840 selectArch("mips2");
4841 getTargetStreamer().emitDirectiveSetMips2();
4843 case Mips::FeatureMips3:
4844 selectArch("mips3");
4845 getTargetStreamer().emitDirectiveSetMips3();
4847 case Mips::FeatureMips4:
4848 selectArch("mips4");
4849 getTargetStreamer().emitDirectiveSetMips4();
4851 case Mips::FeatureMips5:
4852 selectArch("mips5");
4853 getTargetStreamer().emitDirectiveSetMips5();
4855 case Mips::FeatureMips32:
4856 selectArch("mips32");
4857 getTargetStreamer().emitDirectiveSetMips32();
4859 case Mips::FeatureMips32r2:
4860 selectArch("mips32r2");
4861 getTargetStreamer().emitDirectiveSetMips32R2();
4863 case Mips::FeatureMips32r3:
4864 selectArch("mips32r3");
4865 getTargetStreamer().emitDirectiveSetMips32R3();
4867 case Mips::FeatureMips32r5:
4868 selectArch("mips32r5");
4869 getTargetStreamer().emitDirectiveSetMips32R5();
4871 case Mips::FeatureMips32r6:
4872 selectArch("mips32r6");
4873 getTargetStreamer().emitDirectiveSetMips32R6();
4875 case Mips::FeatureMips64:
4876 selectArch("mips64");
4877 getTargetStreamer().emitDirectiveSetMips64();
4879 case Mips::FeatureMips64r2:
4880 selectArch("mips64r2");
4881 getTargetStreamer().emitDirectiveSetMips64R2();
4883 case Mips::FeatureMips64r3:
4884 selectArch("mips64r3");
4885 getTargetStreamer().emitDirectiveSetMips64R3();
4887 case Mips::FeatureMips64r5:
4888 selectArch("mips64r5");
4889 getTargetStreamer().emitDirectiveSetMips64R5();
4891 case Mips::FeatureMips64r6:
4892 selectArch("mips64r6");
4893 getTargetStreamer().emitDirectiveSetMips64R6();
4899 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4900 MCAsmParser &Parser = getParser();
4901 if (getLexer().isNot(AsmToken::Comma)) {
4902 SMLoc Loc = getLexer().getLoc();
4903 Parser.eatToEndOfStatement();
4904 return Error(Loc, ErrorStr);
4907 Parser.Lex(); // Eat the comma.
4911 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4912 // In this class, it is only used for .cprestore.
4913 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4914 // MipsTargetELFStreamer and MipsAsmParser.
4915 bool MipsAsmParser::isPicAndNotNxxAbi() {
4916 return inPicMode() && !(isABI_N32() || isABI_N64());
4919 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4920 if (AssemblerOptions.back()->isReorder())
4921 Warning(Loc, ".cpload should be inside a noreorder section");
4923 if (inMips16Mode()) {
4924 reportParseError(".cpload is not supported in Mips16 mode");
4928 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4929 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4930 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4931 reportParseError("expected register containing function address");
4935 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4936 if (!RegOpnd.isGPRAsmReg()) {
4937 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4941 // If this is not the end of the statement, report an error.
4942 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4943 reportParseError("unexpected token, expected end of statement");
4947 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4951 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4952 MCAsmParser &Parser = getParser();
4954 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4955 // is used in non-PIC mode.
4957 if (inMips16Mode()) {
4958 reportParseError(".cprestore is not supported in Mips16 mode");
4962 // Get the stack offset value.
4963 const MCExpr *StackOffset;
4964 int64_t StackOffsetVal;
4965 if (Parser.parseExpression(StackOffset)) {
4966 reportParseError("expected stack offset value");
4970 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4971 reportParseError("stack offset is not an absolute expression");
4975 if (StackOffsetVal < 0) {
4976 Warning(Loc, ".cprestore with negative stack offset has no effect");
4977 IsCpRestoreSet = false;
4979 IsCpRestoreSet = true;
4980 CpRestoreOffset = StackOffsetVal;
4983 // If this is not the end of the statement, report an error.
4984 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4985 reportParseError("unexpected token, expected end of statement");
4989 // Store the $gp on the stack.
4990 SmallVector<MCInst, 3> StoreInsts;
4991 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
4994 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
4995 Parser.Lex(); // Consume the EndOfStatement.
4999 bool MipsAsmParser::parseDirectiveCPSetup() {
5000 MCAsmParser &Parser = getParser();
5003 bool SaveIsReg = true;
5005 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5006 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5007 if (ResTy == MatchOperand_NoMatch) {
5008 reportParseError("expected register containing function address");
5009 Parser.eatToEndOfStatement();
5013 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5014 if (!FuncRegOpnd.isGPRAsmReg()) {
5015 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5016 Parser.eatToEndOfStatement();
5020 FuncReg = FuncRegOpnd.getGPR32Reg();
5023 if (!eatComma("unexpected token, expected comma"))
5026 ResTy = parseAnyRegister(TmpReg);
5027 if (ResTy == MatchOperand_NoMatch) {
5028 const MCExpr *OffsetExpr;
5030 SMLoc ExprLoc = getLexer().getLoc();
5032 if (Parser.parseExpression(OffsetExpr) ||
5033 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5034 reportParseError(ExprLoc, "expected save register or stack offset");
5035 Parser.eatToEndOfStatement();
5042 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5043 if (!SaveOpnd.isGPRAsmReg()) {
5044 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5045 Parser.eatToEndOfStatement();
5048 Save = SaveOpnd.getGPR32Reg();
5051 if (!eatComma("unexpected token, expected comma"))
5055 if (Parser.parseExpression(Expr)) {
5056 reportParseError("expected expression");
5060 if (Expr->getKind() != MCExpr::SymbolRef) {
5061 reportParseError("expected symbol");
5064 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5066 CpSaveLocation = Save;
5067 CpSaveLocationIsRegister = SaveIsReg;
5069 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5074 bool MipsAsmParser::parseDirectiveCPReturn() {
5075 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5076 CpSaveLocationIsRegister);
5080 bool MipsAsmParser::parseDirectiveNaN() {
5081 MCAsmParser &Parser = getParser();
5082 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5083 const AsmToken &Tok = Parser.getTok();
5085 if (Tok.getString() == "2008") {
5087 getTargetStreamer().emitDirectiveNaN2008();
5089 } else if (Tok.getString() == "legacy") {
5091 getTargetStreamer().emitDirectiveNaNLegacy();
5095 // If we don't recognize the option passed to the .nan
5096 // directive (e.g. no option or unknown option), emit an error.
5097 reportParseError("invalid option in .nan directive");
5101 bool MipsAsmParser::parseDirectiveSet() {
5102 MCAsmParser &Parser = getParser();
5103 // Get the next token.
5104 const AsmToken &Tok = Parser.getTok();
5106 if (Tok.getString() == "noat") {
5107 return parseSetNoAtDirective();
5108 } else if (Tok.getString() == "at") {
5109 return parseSetAtDirective();
5110 } else if (Tok.getString() == "arch") {
5111 return parseSetArchDirective();
5112 } else if (Tok.getString() == "fp") {
5113 return parseSetFpDirective();
5114 } else if (Tok.getString() == "oddspreg") {
5115 return parseSetOddSPRegDirective();
5116 } else if (Tok.getString() == "nooddspreg") {
5117 return parseSetNoOddSPRegDirective();
5118 } else if (Tok.getString() == "pop") {
5119 return parseSetPopDirective();
5120 } else if (Tok.getString() == "push") {
5121 return parseSetPushDirective();
5122 } else if (Tok.getString() == "reorder") {
5123 return parseSetReorderDirective();
5124 } else if (Tok.getString() == "noreorder") {
5125 return parseSetNoReorderDirective();
5126 } else if (Tok.getString() == "macro") {
5127 return parseSetMacroDirective();
5128 } else if (Tok.getString() == "nomacro") {
5129 return parseSetNoMacroDirective();
5130 } else if (Tok.getString() == "mips16") {
5131 return parseSetMips16Directive();
5132 } else if (Tok.getString() == "nomips16") {
5133 return parseSetNoMips16Directive();
5134 } else if (Tok.getString() == "nomicromips") {
5135 getTargetStreamer().emitDirectiveSetNoMicroMips();
5136 Parser.eatToEndOfStatement();
5138 } else if (Tok.getString() == "micromips") {
5139 return parseSetFeature(Mips::FeatureMicroMips);
5140 } else if (Tok.getString() == "mips0") {
5141 return parseSetMips0Directive();
5142 } else if (Tok.getString() == "mips1") {
5143 return parseSetFeature(Mips::FeatureMips1);
5144 } else if (Tok.getString() == "mips2") {
5145 return parseSetFeature(Mips::FeatureMips2);
5146 } else if (Tok.getString() == "mips3") {
5147 return parseSetFeature(Mips::FeatureMips3);
5148 } else if (Tok.getString() == "mips4") {
5149 return parseSetFeature(Mips::FeatureMips4);
5150 } else if (Tok.getString() == "mips5") {
5151 return parseSetFeature(Mips::FeatureMips5);
5152 } else if (Tok.getString() == "mips32") {
5153 return parseSetFeature(Mips::FeatureMips32);
5154 } else if (Tok.getString() == "mips32r2") {
5155 return parseSetFeature(Mips::FeatureMips32r2);
5156 } else if (Tok.getString() == "mips32r3") {
5157 return parseSetFeature(Mips::FeatureMips32r3);
5158 } else if (Tok.getString() == "mips32r5") {
5159 return parseSetFeature(Mips::FeatureMips32r5);
5160 } else if (Tok.getString() == "mips32r6") {
5161 return parseSetFeature(Mips::FeatureMips32r6);
5162 } else if (Tok.getString() == "mips64") {
5163 return parseSetFeature(Mips::FeatureMips64);
5164 } else if (Tok.getString() == "mips64r2") {
5165 return parseSetFeature(Mips::FeatureMips64r2);
5166 } else if (Tok.getString() == "mips64r3") {
5167 return parseSetFeature(Mips::FeatureMips64r3);
5168 } else if (Tok.getString() == "mips64r5") {
5169 return parseSetFeature(Mips::FeatureMips64r5);
5170 } else if (Tok.getString() == "mips64r6") {
5171 return parseSetFeature(Mips::FeatureMips64r6);
5172 } else if (Tok.getString() == "dsp") {
5173 return parseSetFeature(Mips::FeatureDSP);
5174 } else if (Tok.getString() == "nodsp") {
5175 return parseSetNoDspDirective();
5176 } else if (Tok.getString() == "msa") {
5177 return parseSetMsaDirective();
5178 } else if (Tok.getString() == "nomsa") {
5179 return parseSetNoMsaDirective();
5180 } else if (Tok.getString() == "softfloat") {
5181 return parseSetSoftFloatDirective();
5182 } else if (Tok.getString() == "hardfloat") {
5183 return parseSetHardFloatDirective();
5185 // It is just an identifier, look for an assignment.
5186 parseSetAssignment();
5193 /// parseDataDirective
5194 /// ::= .word [ expression (, expression)* ]
5195 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5196 MCAsmParser &Parser = getParser();
5197 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5199 const MCExpr *Value;
5200 if (getParser().parseExpression(Value))
5203 getParser().getStreamer().EmitValue(Value, Size);
5205 if (getLexer().is(AsmToken::EndOfStatement))
5208 if (getLexer().isNot(AsmToken::Comma))
5209 return Error(L, "unexpected token, expected comma");
5218 /// parseDirectiveGpWord
5219 /// ::= .gpword local_sym
5220 bool MipsAsmParser::parseDirectiveGpWord() {
5221 MCAsmParser &Parser = getParser();
5222 const MCExpr *Value;
5223 // EmitGPRel32Value requires an expression, so we are using base class
5224 // method to evaluate the expression.
5225 if (getParser().parseExpression(Value))
5227 getParser().getStreamer().EmitGPRel32Value(Value);
5229 if (getLexer().isNot(AsmToken::EndOfStatement))
5230 return Error(getLexer().getLoc(),
5231 "unexpected token, expected end of statement");
5232 Parser.Lex(); // Eat EndOfStatement token.
5236 /// parseDirectiveGpDWord
5237 /// ::= .gpdword local_sym
5238 bool MipsAsmParser::parseDirectiveGpDWord() {
5239 MCAsmParser &Parser = getParser();
5240 const MCExpr *Value;
5241 // EmitGPRel64Value requires an expression, so we are using base class
5242 // method to evaluate the expression.
5243 if (getParser().parseExpression(Value))
5245 getParser().getStreamer().EmitGPRel64Value(Value);
5247 if (getLexer().isNot(AsmToken::EndOfStatement))
5248 return Error(getLexer().getLoc(),
5249 "unexpected token, expected end of statement");
5250 Parser.Lex(); // Eat EndOfStatement token.
5254 bool MipsAsmParser::parseDirectiveOption() {
5255 MCAsmParser &Parser = getParser();
5256 // Get the option token.
5257 AsmToken Tok = Parser.getTok();
5258 // At the moment only identifiers are supported.
5259 if (Tok.isNot(AsmToken::Identifier)) {
5260 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5261 Parser.eatToEndOfStatement();
5265 StringRef Option = Tok.getIdentifier();
5267 if (Option == "pic0") {
5268 // MipsAsmParser needs to know if the current PIC mode changes.
5269 IsPicEnabled = false;
5271 getTargetStreamer().emitDirectiveOptionPic0();
5273 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5274 Error(Parser.getTok().getLoc(),
5275 "unexpected token, expected end of statement");
5276 Parser.eatToEndOfStatement();
5281 if (Option == "pic2") {
5282 // MipsAsmParser needs to know if the current PIC mode changes.
5283 IsPicEnabled = true;
5285 getTargetStreamer().emitDirectiveOptionPic2();
5287 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5288 Error(Parser.getTok().getLoc(),
5289 "unexpected token, expected end of statement");
5290 Parser.eatToEndOfStatement();
5296 Warning(Parser.getTok().getLoc(),
5297 "unknown option, expected 'pic0' or 'pic2'");
5298 Parser.eatToEndOfStatement();
5302 /// parseInsnDirective
5304 bool MipsAsmParser::parseInsnDirective() {
5305 // If this is not the end of the statement, report an error.
5306 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5307 reportParseError("unexpected token, expected end of statement");
5311 // The actual label marking happens in
5312 // MipsELFStreamer::createPendingLabelRelocs().
5313 getTargetStreamer().emitDirectiveInsn();
5315 getParser().Lex(); // Eat EndOfStatement token.
5319 /// parseDirectiveModule
5320 /// ::= .module oddspreg
5321 /// ::= .module nooddspreg
5322 /// ::= .module fp=value
5323 /// ::= .module softfloat
5324 /// ::= .module hardfloat
5325 bool MipsAsmParser::parseDirectiveModule() {
5326 MCAsmParser &Parser = getParser();
5327 MCAsmLexer &Lexer = getLexer();
5328 SMLoc L = Lexer.getLoc();
5330 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5331 // TODO : get a better message.
5332 reportParseError(".module directive must appear before any code");
5337 if (Parser.parseIdentifier(Option)) {
5338 reportParseError("expected .module option identifier");
5342 if (Option == "oddspreg") {
5343 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5345 // Synchronize the abiflags information with the FeatureBits information we
5347 getTargetStreamer().updateABIInfo(*this);
5349 // If printing assembly, use the recently updated abiflags information.
5350 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5351 // emitted at the end).
5352 getTargetStreamer().emitDirectiveModuleOddSPReg();
5354 // If this is not the end of the statement, report an error.
5355 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5356 reportParseError("unexpected token, expected end of statement");
5360 return false; // parseDirectiveModule has finished successfully.
5361 } else if (Option == "nooddspreg") {
5363 Error(L, "'.module nooddspreg' requires the O32 ABI");
5367 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5369 // Synchronize the abiflags information with the FeatureBits information we
5371 getTargetStreamer().updateABIInfo(*this);
5373 // If printing assembly, use the recently updated abiflags information.
5374 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5375 // emitted at the end).
5376 getTargetStreamer().emitDirectiveModuleOddSPReg();
5378 // If this is not the end of the statement, report an error.
5379 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5380 reportParseError("unexpected token, expected end of statement");
5384 return false; // parseDirectiveModule has finished successfully.
5385 } else if (Option == "fp") {
5386 return parseDirectiveModuleFP();
5387 } else if (Option == "softfloat") {
5388 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5390 // Synchronize the ABI Flags information with the FeatureBits information we
5392 getTargetStreamer().updateABIInfo(*this);
5394 // If printing assembly, use the recently updated ABI Flags information.
5395 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5397 getTargetStreamer().emitDirectiveModuleSoftFloat();
5399 // If this is not the end of the statement, report an error.
5400 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5401 reportParseError("unexpected token, expected end of statement");
5405 return false; // parseDirectiveModule has finished successfully.
5406 } else if (Option == "hardfloat") {
5407 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5409 // Synchronize the ABI Flags information with the FeatureBits information we
5411 getTargetStreamer().updateABIInfo(*this);
5413 // If printing assembly, use the recently updated ABI Flags information.
5414 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5416 getTargetStreamer().emitDirectiveModuleHardFloat();
5418 // If this is not the end of the statement, report an error.
5419 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5420 reportParseError("unexpected token, expected end of statement");
5424 return false; // parseDirectiveModule has finished successfully.
5426 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5430 /// parseDirectiveModuleFP
5434 bool MipsAsmParser::parseDirectiveModuleFP() {
5435 MCAsmParser &Parser = getParser();
5436 MCAsmLexer &Lexer = getLexer();
5438 if (Lexer.isNot(AsmToken::Equal)) {
5439 reportParseError("unexpected token, expected equals sign '='");
5442 Parser.Lex(); // Eat '=' token.
5444 MipsABIFlagsSection::FpABIKind FpABI;
5445 if (!parseFpABIValue(FpABI, ".module"))
5448 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5449 reportParseError("unexpected token, expected end of statement");
5453 // Synchronize the abiflags information with the FeatureBits information we
5455 getTargetStreamer().updateABIInfo(*this);
5457 // If printing assembly, use the recently updated abiflags information.
5458 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5459 // emitted at the end).
5460 getTargetStreamer().emitDirectiveModuleFP();
5462 Parser.Lex(); // Consume the EndOfStatement.
5466 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5467 StringRef Directive) {
5468 MCAsmParser &Parser = getParser();
5469 MCAsmLexer &Lexer = getLexer();
5470 bool ModuleLevelOptions = Directive == ".module";
5472 if (Lexer.is(AsmToken::Identifier)) {
5473 StringRef Value = Parser.getTok().getString();
5476 if (Value != "xx") {
5477 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5482 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5486 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5487 if (ModuleLevelOptions) {
5488 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5489 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5491 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5492 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5497 if (Lexer.is(AsmToken::Integer)) {
5498 unsigned Value = Parser.getTok().getIntVal();
5501 if (Value != 32 && Value != 64) {
5502 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5508 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5512 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5513 if (ModuleLevelOptions) {
5514 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5515 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5517 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5518 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5521 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5522 if (ModuleLevelOptions) {
5523 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5524 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5526 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5527 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5537 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5538 MCAsmParser &Parser = getParser();
5539 StringRef IDVal = DirectiveID.getString();
5541 if (IDVal == ".cpload")
5542 return parseDirectiveCpLoad(DirectiveID.getLoc());
5543 if (IDVal == ".cprestore")
5544 return parseDirectiveCpRestore(DirectiveID.getLoc());
5545 if (IDVal == ".dword") {
5546 parseDataDirective(8, DirectiveID.getLoc());
5549 if (IDVal == ".ent") {
5550 StringRef SymbolName;
5552 if (Parser.parseIdentifier(SymbolName)) {
5553 reportParseError("expected identifier after .ent");
5557 // There's an undocumented extension that allows an integer to
5558 // follow the name of the procedure which AFAICS is ignored by GAS.
5559 // Example: .ent foo,2
5560 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5561 if (getLexer().isNot(AsmToken::Comma)) {
5562 // Even though we accept this undocumented extension for compatibility
5563 // reasons, the additional integer argument does not actually change
5564 // the behaviour of the '.ent' directive, so we would like to discourage
5565 // its use. We do this by not referring to the extended version in
5566 // error messages which are not directly related to its use.
5567 reportParseError("unexpected token, expected end of statement");
5570 Parser.Lex(); // Eat the comma.
5571 const MCExpr *DummyNumber;
5572 int64_t DummyNumberVal;
5573 // If the user was explicitly trying to use the extended version,
5574 // we still give helpful extension-related error messages.
5575 if (Parser.parseExpression(DummyNumber)) {
5576 reportParseError("expected number after comma");
5579 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5580 reportParseError("expected an absolute expression after comma");
5585 // If this is not the end of the statement, report an error.
5586 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5587 reportParseError("unexpected token, expected end of statement");
5591 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5593 getTargetStreamer().emitDirectiveEnt(*Sym);
5595 IsCpRestoreSet = false;
5599 if (IDVal == ".end") {
5600 StringRef SymbolName;
5602 if (Parser.parseIdentifier(SymbolName)) {
5603 reportParseError("expected identifier after .end");
5607 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5608 reportParseError("unexpected token, expected end of statement");
5612 if (CurrentFn == nullptr) {
5613 reportParseError(".end used without .ent");
5617 if ((SymbolName != CurrentFn->getName())) {
5618 reportParseError(".end symbol does not match .ent symbol");
5622 getTargetStreamer().emitDirectiveEnd(SymbolName);
5623 CurrentFn = nullptr;
5624 IsCpRestoreSet = false;
5628 if (IDVal == ".frame") {
5629 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5630 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5631 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5632 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5633 reportParseError("expected stack register");
5637 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5638 if (!StackRegOpnd.isGPRAsmReg()) {
5639 reportParseError(StackRegOpnd.getStartLoc(),
5640 "expected general purpose register");
5643 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5645 if (Parser.getTok().is(AsmToken::Comma))
5648 reportParseError("unexpected token, expected comma");
5652 // Parse the frame size.
5653 const MCExpr *FrameSize;
5654 int64_t FrameSizeVal;
5656 if (Parser.parseExpression(FrameSize)) {
5657 reportParseError("expected frame size value");
5661 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5662 reportParseError("frame size not an absolute expression");
5666 if (Parser.getTok().is(AsmToken::Comma))
5669 reportParseError("unexpected token, expected comma");
5673 // Parse the return register.
5675 ResTy = parseAnyRegister(TmpReg);
5676 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5677 reportParseError("expected return register");
5681 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5682 if (!ReturnRegOpnd.isGPRAsmReg()) {
5683 reportParseError(ReturnRegOpnd.getStartLoc(),
5684 "expected general purpose register");
5688 // If this is not the end of the statement, report an error.
5689 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5690 reportParseError("unexpected token, expected end of statement");
5694 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5695 ReturnRegOpnd.getGPR32Reg());
5696 IsCpRestoreSet = false;
5700 if (IDVal == ".set") {
5701 return parseDirectiveSet();
5704 if (IDVal == ".mask" || IDVal == ".fmask") {
5705 // .mask bitmask, frame_offset
5706 // bitmask: One bit for each register used.
5707 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5708 // first register is expected to be saved.
5710 // .mask 0x80000000, -4
5711 // .fmask 0x80000000, -4
5714 // Parse the bitmask
5715 const MCExpr *BitMask;
5718 if (Parser.parseExpression(BitMask)) {
5719 reportParseError("expected bitmask value");
5723 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5724 reportParseError("bitmask not an absolute expression");
5728 if (Parser.getTok().is(AsmToken::Comma))
5731 reportParseError("unexpected token, expected comma");
5735 // Parse the frame_offset
5736 const MCExpr *FrameOffset;
5737 int64_t FrameOffsetVal;
5739 if (Parser.parseExpression(FrameOffset)) {
5740 reportParseError("expected frame offset value");
5744 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5745 reportParseError("frame offset not an absolute expression");
5749 // If this is not the end of the statement, report an error.
5750 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5751 reportParseError("unexpected token, expected end of statement");
5755 if (IDVal == ".mask")
5756 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5758 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5762 if (IDVal == ".nan")
5763 return parseDirectiveNaN();
5765 if (IDVal == ".gpword") {
5766 parseDirectiveGpWord();
5770 if (IDVal == ".gpdword") {
5771 parseDirectiveGpDWord();
5775 if (IDVal == ".word") {
5776 parseDataDirective(4, DirectiveID.getLoc());
5780 if (IDVal == ".option")
5781 return parseDirectiveOption();
5783 if (IDVal == ".abicalls") {
5784 getTargetStreamer().emitDirectiveAbiCalls();
5785 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5786 Error(Parser.getTok().getLoc(),
5787 "unexpected token, expected end of statement");
5789 Parser.eatToEndOfStatement();
5794 if (IDVal == ".cpsetup")
5795 return parseDirectiveCPSetup();
5797 if (IDVal == ".cpreturn")
5798 return parseDirectiveCPReturn();
5800 if (IDVal == ".module")
5801 return parseDirectiveModule();
5803 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5804 return parseInternalDirectiveReallowModule();
5806 if (IDVal == ".insn")
5807 return parseInsnDirective();
5812 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5813 // If this is not the end of the statement, report an error.
5814 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5815 reportParseError("unexpected token, expected end of statement");
5819 getTargetStreamer().reallowModuleDirective();
5821 getParser().Lex(); // Eat EndOfStatement token.
5825 extern "C" void LLVMInitializeMipsAsmParser() {
5826 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5827 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5828 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5829 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5832 #define GET_REGISTER_MATCHER
5833 #define GET_MATCHER_IMPLEMENTATION
5834 #include "MipsGenAsmMatcher.inc"