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 expandUlh(MCInst &Inst, bool Signed, 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:
1970 if ((Inst.getNumOperands() == 3) &&
1971 Inst.getOperand(0).isReg() &&
1972 Inst.getOperand(1).isReg() &&
1973 Inst.getOperand(2).isImm()) {
1974 int64_t ImmValue = Inst.getOperand(2).getImm();
1975 return !isInt<16>(ImmValue);
1981 if ((Inst.getNumOperands() == 3) &&
1982 Inst.getOperand(0).isReg() &&
1983 Inst.getOperand(1).isReg() &&
1984 Inst.getOperand(2).isImm()) {
1985 int64_t ImmValue = Inst.getOperand(2).getImm();
1986 return !isUInt<16>(ImmValue);
1994 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1995 SmallVectorImpl<MCInst> &Instructions) {
1996 switch (Inst.getOpcode()) {
1997 default: llvm_unreachable("unimplemented expansion");
1998 case Mips::LoadImm32:
1999 return expandLoadImm(Inst, true, IDLoc, Instructions);
2000 case Mips::LoadImm64:
2001 return expandLoadImm(Inst, false, IDLoc, Instructions);
2002 case Mips::LoadAddrImm32:
2003 case Mips::LoadAddrImm64:
2004 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2005 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2006 "expected immediate operand kind");
2008 return expandLoadAddress(
2009 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
2010 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
2011 case Mips::LoadAddrReg32:
2012 case Mips::LoadAddrReg64:
2013 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2014 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2015 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2016 "expected immediate operand kind");
2018 return expandLoadAddress(
2019 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
2020 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
2021 case Mips::B_MM_Pseudo:
2022 case Mips::B_MMR6_Pseudo:
2023 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
2026 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
2027 case Mips::JalOneReg:
2028 case Mips::JalTwoReg:
2029 return expandJalWithRegs(Inst, IDLoc, Instructions);
2032 return expandBranchImm(Inst, IDLoc, Instructions);
2049 case Mips::BLTImmMacro:
2050 case Mips::BLEImmMacro:
2051 case Mips::BGEImmMacro:
2052 case Mips::BGTImmMacro:
2053 case Mips::BLTUImmMacro:
2054 case Mips::BLEUImmMacro:
2055 case Mips::BGEUImmMacro:
2056 case Mips::BGTUImmMacro:
2057 case Mips::BLTLImmMacro:
2058 case Mips::BLELImmMacro:
2059 case Mips::BGELImmMacro:
2060 case Mips::BGTLImmMacro:
2061 case Mips::BLTULImmMacro:
2062 case Mips::BLEULImmMacro:
2063 case Mips::BGEULImmMacro:
2064 case Mips::BGTULImmMacro:
2065 return expandCondBranches(Inst, IDLoc, Instructions);
2066 case Mips::SDivMacro:
2067 return expandDiv(Inst, IDLoc, Instructions, false, true);
2068 case Mips::DSDivMacro:
2069 return expandDiv(Inst, IDLoc, Instructions, true, true);
2070 case Mips::UDivMacro:
2071 return expandDiv(Inst, IDLoc, Instructions, false, false);
2072 case Mips::DUDivMacro:
2073 return expandDiv(Inst, IDLoc, Instructions, true, false);
2075 return expandUlh(Inst, true, IDLoc, Instructions);
2077 return expandUlh(Inst, false, IDLoc, Instructions);
2079 return expandUlw(Inst, IDLoc, Instructions);
2088 return expandAliasImmediate(Inst, IDLoc, Instructions);
2092 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2093 SmallVectorImpl<MCInst> &Instructions) {
2094 // Create a JALR instruction which is going to replace the pseudo-JAL.
2096 JalrInst.setLoc(IDLoc);
2097 const MCOperand FirstRegOp = Inst.getOperand(0);
2098 const unsigned Opcode = Inst.getOpcode();
2100 if (Opcode == Mips::JalOneReg) {
2101 // jal $rs => jalr $rs
2102 if (IsCpRestoreSet && inMicroMipsMode()) {
2103 JalrInst.setOpcode(Mips::JALRS16_MM);
2104 JalrInst.addOperand(FirstRegOp);
2105 } else if (inMicroMipsMode()) {
2106 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2107 JalrInst.addOperand(FirstRegOp);
2109 JalrInst.setOpcode(Mips::JALR);
2110 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2111 JalrInst.addOperand(FirstRegOp);
2113 } else if (Opcode == Mips::JalTwoReg) {
2114 // jal $rd, $rs => jalr $rd, $rs
2115 if (IsCpRestoreSet && inMicroMipsMode())
2116 JalrInst.setOpcode(Mips::JALRS_MM);
2118 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2119 JalrInst.addOperand(FirstRegOp);
2120 const MCOperand SecondRegOp = Inst.getOperand(1);
2121 JalrInst.addOperand(SecondRegOp);
2123 Instructions.push_back(JalrInst);
2125 // If .set reorder is active and branch instruction has a delay slot,
2126 // emit a NOP after it.
2127 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2128 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2129 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2135 /// Can the value be represented by a unsigned N-bit value and a shift left?
2136 template<unsigned N>
2137 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2138 unsigned BitNum = findFirstSet(x);
2140 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2143 /// Load (or add) an immediate into a register.
2145 /// @param ImmValue The immediate to load.
2146 /// @param DstReg The register that will hold the immediate.
2147 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2148 /// for a simple initialization.
2149 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2150 /// @param IsAddress True if the immediate represents an address. False if it
2152 /// @param IDLoc Location of the immediate in the source file.
2153 /// @param Instructions The instructions emitted by this expansion.
2154 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2155 unsigned SrcReg, bool Is32BitImm,
2156 bool IsAddress, SMLoc IDLoc,
2157 SmallVectorImpl<MCInst> &Instructions) {
2158 if (!Is32BitImm && !isGP64bit()) {
2159 Error(IDLoc, "instruction requires a 64-bit architecture");
2164 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2165 // Sign extend up to 64-bit so that the predicates match the hardware
2166 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2168 ImmValue = SignExtend64<32>(ImmValue);
2170 Error(IDLoc, "instruction requires a 32-bit immediate");
2175 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2176 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2178 bool UseSrcReg = false;
2179 if (SrcReg != Mips::NoRegister)
2182 unsigned TmpReg = DstReg;
2183 if (UseSrcReg && (DstReg == SrcReg)) {
2184 // At this point we need AT to perform the expansions and we exit if it is
2186 unsigned ATReg = getATReg(IDLoc);
2192 if (isInt<16>(ImmValue)) {
2196 // This doesn't quite follow the usual ABI expectations for N32 but matches
2197 // traditional assembler behaviour. N32 would normally use addiu for both
2198 // integers and addresses.
2199 if (IsAddress && !Is32BitImm) {
2200 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2204 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2208 if (isUInt<16>(ImmValue)) {
2209 unsigned TmpReg = DstReg;
2210 if (SrcReg == DstReg) {
2211 TmpReg = getATReg(IDLoc);
2216 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2218 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2222 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2223 warnIfNoMacro(IDLoc);
2225 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2226 uint16_t Bits15To0 = ImmValue & 0xffff;
2228 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2229 // Traditional behaviour seems to special case this particular value. It's
2230 // not clear why other masks are handled differently.
2231 if (ImmValue == 0xffffffff) {
2232 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2233 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2235 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2239 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2241 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2242 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2244 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2246 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2250 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2252 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2254 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2258 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2260 Error(IDLoc, "instruction requires a 32-bit immediate");
2264 // Traditionally, these immediates are shifted as little as possible and as
2265 // such we align the most significant bit to bit 15 of our temporary.
2266 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2267 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2268 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2269 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2270 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2271 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2274 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2279 warnIfNoMacro(IDLoc);
2281 // The remaining case is packed with a sequence of dsll and ori with zeros
2282 // being omitted and any neighbouring dsll's being coalesced.
2283 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2285 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2286 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2287 IDLoc, Instructions))
2290 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2291 // skip it and defer the shift to the next chunk.
2292 unsigned ShiftCarriedForwards = 16;
2293 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2294 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2296 if (ImmChunk != 0) {
2297 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2299 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2300 ShiftCarriedForwards = 0;
2303 ShiftCarriedForwards += 16;
2305 ShiftCarriedForwards -= 16;
2307 // Finish any remaining shifts left by trailing zeros.
2308 if (ShiftCarriedForwards)
2309 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2313 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2318 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2319 SmallVectorImpl<MCInst> &Instructions) {
2320 const MCOperand &ImmOp = Inst.getOperand(1);
2321 assert(ImmOp.isImm() && "expected immediate operand kind");
2322 const MCOperand &DstRegOp = Inst.getOperand(0);
2323 assert(DstRegOp.isReg() && "expected register operand kind");
2325 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2326 Is32BitImm, false, IDLoc, Instructions))
2332 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2333 const MCOperand &Offset,
2334 bool Is32BitAddress, SMLoc IDLoc,
2335 SmallVectorImpl<MCInst> &Instructions) {
2336 // la can't produce a usable address when addresses are 64-bit.
2337 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2338 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2339 // We currently can't do this because we depend on the equality
2340 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2341 Error(IDLoc, "la used to load 64-bit address");
2342 // Continue as if we had 'dla' instead.
2343 Is32BitAddress = false;
2346 // dla requires 64-bit addresses.
2347 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2348 Error(IDLoc, "instruction requires a 64-bit architecture");
2352 if (!Offset.isImm())
2353 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2354 Is32BitAddress, IDLoc, Instructions);
2356 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2357 IDLoc, Instructions);
2360 bool MipsAsmParser::loadAndAddSymbolAddress(
2361 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2362 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2363 warnIfNoMacro(IDLoc);
2365 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2366 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2367 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2368 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2369 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2371 bool UseSrcReg = SrcReg != Mips::NoRegister;
2373 // This is the 64-bit symbol address expansion.
2374 if (ABI.ArePtrs64bit() && isGP64bit()) {
2375 // We always need AT for the 64-bit expansion.
2376 // If it is not available we exit.
2377 unsigned ATReg = getATReg(IDLoc);
2381 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2382 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2383 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2384 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2386 if (UseSrcReg && (DstReg == SrcReg)) {
2387 // If $rs is the same as $rd:
2388 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2389 // daddiu $at, $at, %higher(sym)
2390 // dsll $at, $at, 16
2391 // daddiu $at, $at, %hi(sym)
2392 // dsll $at, $at, 16
2393 // daddiu $at, $at, %lo(sym)
2394 // daddu $rd, $at, $rd
2395 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2397 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2398 IDLoc, Instructions);
2399 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2400 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2402 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2403 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2405 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2410 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2411 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2412 // lui $at, %hi(sym)
2413 // daddiu $rd, $rd, %higher(sym)
2414 // daddiu $at, $at, %lo(sym)
2415 // dsll32 $rd, $rd, 0
2416 // daddu $rd, $rd, $at
2417 // (daddu $rd, $rd, $rs)
2418 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2420 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2422 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2423 IDLoc, Instructions);
2424 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2426 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2427 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2429 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2434 // And now, the 32-bit symbol address expansion:
2435 // If $rs is the same as $rd:
2436 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2437 // ori $at, $at, %lo(sym)
2438 // addu $rd, $at, $rd
2439 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2440 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2441 // ori $rd, $rd, %lo(sym)
2442 // (addu $rd, $rd, $rs)
2443 unsigned TmpReg = DstReg;
2444 if (UseSrcReg && (DstReg == SrcReg)) {
2445 // If $rs is the same as $rd, we need to use AT.
2446 // If it is not available we exit.
2447 unsigned ATReg = getATReg(IDLoc);
2453 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2454 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2458 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2460 assert(DstReg == TmpReg);
2465 bool MipsAsmParser::expandUncondBranchMMPseudo(
2466 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2467 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2468 "unexpected number of operands");
2470 MCOperand Offset = Inst.getOperand(0);
2471 if (Offset.isExpr()) {
2473 Inst.setOpcode(Mips::BEQ_MM);
2474 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2475 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2476 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2478 assert(Offset.isImm() && "expected immediate operand kind");
2479 if (isInt<11>(Offset.getImm())) {
2480 // If offset fits into 11 bits then this instruction becomes microMIPS
2481 // 16-bit unconditional branch instruction.
2482 if (inMicroMipsMode())
2483 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2485 if (!isInt<17>(Offset.getImm()))
2486 Error(IDLoc, "branch target out of range");
2487 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2488 Error(IDLoc, "branch to misaligned address");
2490 Inst.setOpcode(Mips::BEQ_MM);
2491 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2492 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2493 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2496 Instructions.push_back(Inst);
2498 // If .set reorder is active and branch instruction has a delay slot,
2499 // emit a NOP after it.
2500 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2501 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2502 createNop(true, IDLoc, Instructions);
2507 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2508 SmallVectorImpl<MCInst> &Instructions) {
2509 const MCOperand &DstRegOp = Inst.getOperand(0);
2510 assert(DstRegOp.isReg() && "expected register operand kind");
2512 const MCOperand &ImmOp = Inst.getOperand(1);
2513 assert(ImmOp.isImm() && "expected immediate operand kind");
2515 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2516 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2518 unsigned OpCode = 0;
2519 switch(Inst.getOpcode()) {
2527 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2531 int64_t ImmValue = ImmOp.getImm();
2533 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2536 warnIfNoMacro(IDLoc);
2538 unsigned ATReg = getATReg(IDLoc);
2542 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2543 IDLoc, Instructions))
2546 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2551 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2552 SmallVectorImpl<MCInst> &Instructions,
2553 bool isLoad, bool isImmOpnd) {
2554 unsigned ImmOffset, HiOffset, LoOffset;
2555 const MCExpr *ExprOffset;
2557 // 1st operand is either the source or destination register.
2558 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2559 unsigned RegOpNum = Inst.getOperand(0).getReg();
2560 // 2nd operand is the base register.
2561 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2562 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2563 // 3rd operand is either an immediate or expression.
2565 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2566 ImmOffset = Inst.getOperand(2).getImm();
2567 LoOffset = ImmOffset & 0x0000ffff;
2568 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2569 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2570 if (LoOffset & 0x8000)
2573 ExprOffset = Inst.getOperand(2).getExpr();
2574 // These are some of the types of expansions we perform here:
2575 // 1) lw $8, sym => lui $8, %hi(sym)
2576 // lw $8, %lo(sym)($8)
2577 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2579 // lw $8, %lo(offset)($9)
2580 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2582 // lw $8, %lo(offset)($at)
2583 // 4) sw $8, sym => lui $at, %hi(sym)
2584 // sw $8, %lo(sym)($at)
2585 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2587 // sw $8, %lo(offset)($at)
2588 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2589 // ldc1 $f0, %lo(sym)($at)
2591 // For load instructions we can use the destination register as a temporary
2592 // if base and dst are different (examples 1 and 2) and if the base register
2593 // is general purpose otherwise we must use $at (example 6) and error if it's
2594 // not available. For stores we must use $at (examples 4 and 5) because we
2595 // must not clobber the source register setting up the offset.
2596 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2597 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2598 unsigned RegClassIDOp0 =
2599 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2600 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2601 (RegClassIDOp0 == Mips::GPR64RegClassID);
2602 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2603 TmpRegNum = RegOpNum;
2605 // At this point we need AT to perform the expansions and we exit if it is
2607 TmpRegNum = getATReg(IDLoc);
2612 emitRX(Mips::LUi, TmpRegNum,
2613 isImmOpnd ? MCOperand::createImm(HiOffset)
2614 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2615 IDLoc, Instructions);
2616 // Add temp register to base.
2617 if (BaseRegNum != Mips::ZERO)
2618 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2619 // And finally, create original instruction with low part
2620 // of offset and new base.
2621 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2623 ? MCOperand::createImm(LoOffset)
2624 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2625 IDLoc, Instructions);
2629 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2630 SmallVectorImpl<MCInst> &Instructions) {
2631 unsigned OpNum = Inst.getNumOperands();
2632 unsigned Opcode = Inst.getOpcode();
2633 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2635 assert (Inst.getOperand(OpNum - 1).isImm() &&
2636 Inst.getOperand(OpNum - 2).isReg() &&
2637 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2639 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2640 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2641 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2642 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2643 // It can be implemented as SWM16 or LWM16 instruction.
2644 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2646 Inst.setOpcode(NewOpcode);
2647 Instructions.push_back(Inst);
2651 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2652 SmallVectorImpl<MCInst> &Instructions) {
2653 bool EmittedNoMacroWarning = false;
2654 unsigned PseudoOpcode = Inst.getOpcode();
2655 unsigned SrcReg = Inst.getOperand(0).getReg();
2656 const MCOperand &TrgOp = Inst.getOperand(1);
2657 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2659 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2660 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2664 TrgReg = TrgOp.getReg();
2665 else if (TrgOp.isImm()) {
2666 warnIfNoMacro(IDLoc);
2667 EmittedNoMacroWarning = true;
2669 TrgReg = getATReg(IDLoc);
2673 switch(PseudoOpcode) {
2675 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2676 case Mips::BLTImmMacro:
2677 PseudoOpcode = Mips::BLT;
2679 case Mips::BLEImmMacro:
2680 PseudoOpcode = Mips::BLE;
2682 case Mips::BGEImmMacro:
2683 PseudoOpcode = Mips::BGE;
2685 case Mips::BGTImmMacro:
2686 PseudoOpcode = Mips::BGT;
2688 case Mips::BLTUImmMacro:
2689 PseudoOpcode = Mips::BLTU;
2691 case Mips::BLEUImmMacro:
2692 PseudoOpcode = Mips::BLEU;
2694 case Mips::BGEUImmMacro:
2695 PseudoOpcode = Mips::BGEU;
2697 case Mips::BGTUImmMacro:
2698 PseudoOpcode = Mips::BGTU;
2700 case Mips::BLTLImmMacro:
2701 PseudoOpcode = Mips::BLTL;
2703 case Mips::BLELImmMacro:
2704 PseudoOpcode = Mips::BLEL;
2706 case Mips::BGELImmMacro:
2707 PseudoOpcode = Mips::BGEL;
2709 case Mips::BGTLImmMacro:
2710 PseudoOpcode = Mips::BGTL;
2712 case Mips::BLTULImmMacro:
2713 PseudoOpcode = Mips::BLTUL;
2715 case Mips::BLEULImmMacro:
2716 PseudoOpcode = Mips::BLEUL;
2718 case Mips::BGEULImmMacro:
2719 PseudoOpcode = Mips::BGEUL;
2721 case Mips::BGTULImmMacro:
2722 PseudoOpcode = Mips::BGTUL;
2726 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2727 false, IDLoc, Instructions))
2731 switch (PseudoOpcode) {
2736 AcceptsEquality = false;
2737 ReverseOrderSLT = false;
2738 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2739 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2740 ZeroSrcOpcode = Mips::BGTZ;
2741 ZeroTrgOpcode = Mips::BLTZ;
2747 AcceptsEquality = true;
2748 ReverseOrderSLT = true;
2749 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2750 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2751 ZeroSrcOpcode = Mips::BGEZ;
2752 ZeroTrgOpcode = Mips::BLEZ;
2758 AcceptsEquality = true;
2759 ReverseOrderSLT = false;
2760 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2761 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2762 ZeroSrcOpcode = Mips::BLEZ;
2763 ZeroTrgOpcode = Mips::BGEZ;
2769 AcceptsEquality = false;
2770 ReverseOrderSLT = true;
2771 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2772 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2773 ZeroSrcOpcode = Mips::BLTZ;
2774 ZeroTrgOpcode = Mips::BGTZ;
2777 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2780 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2781 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2782 if (IsSrcRegZero && IsTrgRegZero) {
2783 // FIXME: All of these Opcode-specific if's are needed for compatibility
2784 // with GAS' behaviour. However, they may not generate the most efficient
2785 // code in some circumstances.
2786 if (PseudoOpcode == Mips::BLT) {
2787 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2791 if (PseudoOpcode == Mips::BLE) {
2792 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2794 Warning(IDLoc, "branch is always taken");
2797 if (PseudoOpcode == Mips::BGE) {
2798 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2800 Warning(IDLoc, "branch is always taken");
2803 if (PseudoOpcode == Mips::BGT) {
2804 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2808 if (PseudoOpcode == Mips::BGTU) {
2809 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2810 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2813 if (AcceptsEquality) {
2814 // If both registers are $0 and the pseudo-branch accepts equality, it
2815 // will always be taken, so we emit an unconditional branch.
2816 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2817 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2818 Warning(IDLoc, "branch is always taken");
2821 // If both registers are $0 and the pseudo-branch does not accept
2822 // equality, it will never be taken, so we don't have to emit anything.
2825 if (IsSrcRegZero || IsTrgRegZero) {
2826 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2827 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2828 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2829 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2830 // the pseudo-branch will never be taken, so we don't emit anything.
2831 // This only applies to unsigned pseudo-branches.
2834 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2835 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2836 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2837 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2838 // the pseudo-branch will always be taken, so we emit an unconditional
2840 // This only applies to unsigned pseudo-branches.
2841 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2842 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2843 Warning(IDLoc, "branch is always taken");
2847 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2848 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2849 // the pseudo-branch will be taken only when the non-zero register is
2850 // different from 0, so we emit a BNEZ.
2852 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2853 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2854 // the pseudo-branch will be taken only when the non-zero register is
2855 // equal to 0, so we emit a BEQZ.
2857 // Because only BLEU and BGEU branch on equality, we can use the
2858 // AcceptsEquality variable to decide when to emit the BEQZ.
2859 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2860 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2861 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2864 // If we have a signed pseudo-branch and one of the registers is $0,
2865 // we can use an appropriate compare-to-zero branch. We select which one
2866 // to use in the switch statement above.
2867 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2868 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2869 IDLoc, Instructions);
2873 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2874 // expansions. If it is not available, we return.
2875 unsigned ATRegNum = getATReg(IDLoc);
2879 if (!EmittedNoMacroWarning)
2880 warnIfNoMacro(IDLoc);
2882 // SLT fits well with 2 of our 4 pseudo-branches:
2883 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2884 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2885 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2886 // This is accomplished by using a BNEZ with the result of the SLT.
2888 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2889 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2890 // Because only BGE and BLE branch on equality, we can use the
2891 // AcceptsEquality variable to decide when to emit the BEQZ.
2892 // Note that the order of the SLT arguments doesn't change between
2895 // The same applies to the unsigned variants, except that SLTu is used
2897 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2898 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2899 IDLoc, Instructions);
2901 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2902 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2903 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2908 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2909 SmallVectorImpl<MCInst> &Instructions,
2910 const bool IsMips64, const bool Signed) {
2911 if (hasMips32r6()) {
2912 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2916 warnIfNoMacro(IDLoc);
2918 const MCOperand &RsRegOp = Inst.getOperand(0);
2919 assert(RsRegOp.isReg() && "expected register operand kind");
2920 unsigned RsReg = RsRegOp.getReg();
2922 const MCOperand &RtRegOp = Inst.getOperand(1);
2923 assert(RtRegOp.isReg() && "expected register operand kind");
2924 unsigned RtReg = RtRegOp.getReg();
2929 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2930 ZeroReg = Mips::ZERO_64;
2932 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2933 ZeroReg = Mips::ZERO;
2936 bool UseTraps = useTraps();
2938 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2939 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2940 Warning(IDLoc, "dividing zero by zero");
2942 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2944 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2948 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2952 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2957 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2958 Warning(IDLoc, "division by zero");
2961 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2965 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2970 // FIXME: The values for these two BranchTarget variables may be different in
2971 // micromips. These magic numbers need to be removed.
2972 unsigned BranchTargetNoTraps;
2973 unsigned BranchTarget;
2976 BranchTarget = IsMips64 ? 12 : 8;
2977 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2979 BranchTarget = IsMips64 ? 20 : 16;
2980 BranchTargetNoTraps = 8;
2981 // Branch to the li instruction.
2982 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2986 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2989 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2992 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2996 unsigned ATReg = getATReg(IDLoc);
3000 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
3002 // Branch to the mflo instruction.
3003 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3004 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
3005 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
3007 // Branch to the mflo instruction.
3008 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3009 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
3013 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
3015 // Branch to the mflo instruction.
3016 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
3017 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
3018 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
3020 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3024 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3025 SmallVectorImpl<MCInst> &Instructions) {
3026 if (hasMips32r6() || hasMips64r6()) {
3027 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3031 warnIfNoMacro(IDLoc);
3033 const MCOperand &DstRegOp = Inst.getOperand(0);
3034 assert(DstRegOp.isReg() && "expected register operand kind");
3036 const MCOperand &SrcRegOp = Inst.getOperand(1);
3037 assert(SrcRegOp.isReg() && "expected register operand kind");
3039 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3040 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3042 unsigned DstReg = DstRegOp.getReg();
3043 unsigned SrcReg = SrcRegOp.getReg();
3044 int64_t OffsetValue = OffsetImmOp.getImm();
3046 // NOTE: We always need AT for ULHU, as it is always used as the source
3047 // register for one of the LBu's.
3048 unsigned ATReg = getATReg(IDLoc);
3052 // When the value of offset+1 does not fit in 16 bits, we have to load the
3053 // offset in AT, (D)ADDu the original source register (if there was one), and
3054 // then use AT as the source register for the 2 generated LBu's.
3055 bool LoadedOffsetInAT = false;
3056 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3057 LoadedOffsetInAT = true;
3059 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3060 true, IDLoc, Instructions))
3063 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3064 // because it will make our output more similar to GAS'. For example,
3065 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3066 // instead of just an "ori $1, $9, 32768".
3067 // NOTE: If there is no source register specified in the ULHU, the parser
3068 // will interpret it as $0.
3069 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3070 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3073 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3074 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3075 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3077 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3079 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3080 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3082 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3083 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3086 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3088 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3089 FirstLbuOffset, IDLoc, Instructions);
3091 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3094 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3096 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3101 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3102 SmallVectorImpl<MCInst> &Instructions) {
3103 if (hasMips32r6() || hasMips64r6()) {
3104 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3108 const MCOperand &DstRegOp = Inst.getOperand(0);
3109 assert(DstRegOp.isReg() && "expected register operand kind");
3111 const MCOperand &SrcRegOp = Inst.getOperand(1);
3112 assert(SrcRegOp.isReg() && "expected register operand kind");
3114 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3115 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3117 unsigned SrcReg = SrcRegOp.getReg();
3118 int64_t OffsetValue = OffsetImmOp.getImm();
3121 // When the value of offset+3 does not fit in 16 bits, we have to load the
3122 // offset in AT, (D)ADDu the original source register (if there was one), and
3123 // then use AT as the source register for the generated LWL and LWR.
3124 bool LoadedOffsetInAT = false;
3125 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3126 ATReg = getATReg(IDLoc);
3129 LoadedOffsetInAT = true;
3131 warnIfNoMacro(IDLoc);
3133 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3134 true, IDLoc, Instructions))
3137 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3138 // because it will make our output more similar to GAS'. For example,
3139 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3140 // instead of just an "ori $1, $9, 32768".
3141 // NOTE: If there is no source register specified in the ULW, the parser
3142 // will interpret it as $0.
3143 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3144 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3147 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3148 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3150 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3151 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3153 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3154 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3157 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3160 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3166 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3167 SmallVectorImpl<MCInst> &Instructions) {
3169 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3170 assert (Inst.getOperand(0).isReg() &&
3171 Inst.getOperand(1).isReg() &&
3172 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3174 unsigned ATReg = Mips::NoRegister;
3175 unsigned FinalDstReg = Mips::NoRegister;
3176 unsigned DstReg = Inst.getOperand(0).getReg();
3177 unsigned SrcReg = Inst.getOperand(1).getReg();
3178 int64_t ImmValue = Inst.getOperand(2).getImm();
3180 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3182 unsigned FinalOpcode = Inst.getOpcode();
3184 if (DstReg == SrcReg) {
3185 ATReg = getATReg(Inst.getLoc());
3188 FinalDstReg = DstReg;
3192 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3193 switch (FinalOpcode) {
3195 llvm_unreachable("unimplemented expansion");
3197 FinalOpcode = Mips::ADD;
3200 FinalOpcode = Mips::ADDu;
3203 FinalOpcode = Mips::AND;
3205 case (Mips::NORImm):
3206 FinalOpcode = Mips::NOR;
3209 FinalOpcode = Mips::OR;
3212 FinalOpcode = Mips::SLT;
3215 FinalOpcode = Mips::SLTu;
3218 FinalOpcode = Mips::XOR;
3222 if (FinalDstReg == Mips::NoRegister)
3223 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3225 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3232 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3233 SmallVectorImpl<MCInst> &Instructions) {
3234 if (hasShortDelaySlot)
3235 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3237 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3240 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3241 unsigned TrgReg, bool Is64Bit,
3242 SmallVectorImpl<MCInst> &Instructions) {
3243 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3247 void MipsAsmParser::createCpRestoreMemOp(
3248 bool IsLoad, int StackOffset, SMLoc IDLoc,
3249 SmallVectorImpl<MCInst> &Instructions) {
3250 // If the offset can not fit into 16 bits, we need to expand.
3251 if (!isInt<16>(StackOffset)) {
3253 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3254 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3255 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3256 MemInst.addOperand(MCOperand::createImm(StackOffset));
3257 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3261 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3265 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3266 // As described by the Mips32r2 spec, the registers Rd and Rs for
3267 // jalr.hb must be different.
3268 unsigned Opcode = Inst.getOpcode();
3270 if (Opcode == Mips::JALR_HB &&
3271 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3272 return Match_RequiresDifferentSrcAndDst;
3274 return Match_Success;
3277 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3278 OperandVector &Operands,
3280 uint64_t &ErrorInfo,
3281 bool MatchingInlineAsm) {
3284 SmallVector<MCInst, 8> Instructions;
3285 unsigned MatchResult =
3286 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3288 switch (MatchResult) {
3289 case Match_Success: {
3290 if (processInstruction(Inst, IDLoc, Instructions))
3292 for (unsigned i = 0; i < Instructions.size(); i++)
3293 Out.EmitInstruction(Instructions[i], STI);
3296 case Match_MissingFeature:
3297 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3299 case Match_InvalidOperand: {
3300 SMLoc ErrorLoc = IDLoc;
3301 if (ErrorInfo != ~0ULL) {
3302 if (ErrorInfo >= Operands.size())
3303 return Error(IDLoc, "too few operands for instruction");
3305 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3306 if (ErrorLoc == SMLoc())
3310 return Error(ErrorLoc, "invalid operand for instruction");
3312 case Match_MnemonicFail:
3313 return Error(IDLoc, "invalid instruction");
3314 case Match_RequiresDifferentSrcAndDst:
3315 return Error(IDLoc, "source and destination must be different");
3318 llvm_unreachable("Implement any new match types added!");
3321 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3322 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3323 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3324 ") without \".set noat\"");
3327 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3328 if (!AssemblerOptions.back()->isMacro())
3329 Warning(Loc, "macro instruction expanded into multiple instructions");
3333 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3334 SMRange Range, bool ShowColors) {
3335 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3336 Range, SMFixIt(Range, FixMsg),
3340 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3343 CC = StringSwitch<unsigned>(Name)
3379 if (!(isABI_N32() || isABI_N64()))
3382 if (12 <= CC && CC <= 15) {
3383 // Name is one of t4-t7
3384 AsmToken RegTok = getLexer().peekTok();
3385 SMRange RegRange = RegTok.getLocRange();
3387 StringRef FixedName = StringSwitch<StringRef>(Name)
3393 assert(FixedName != "" && "Register name is not one of t4-t7.");
3395 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3396 "Did you mean $" + FixedName + "?", RegRange);
3399 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3400 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3401 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3402 if (8 <= CC && CC <= 11)
3406 CC = StringSwitch<unsigned>(Name)
3418 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3421 CC = StringSwitch<unsigned>(Name)
3422 .Case("hwr_cpunum", 0)
3423 .Case("hwr_synci_step", 1)
3425 .Case("hwr_ccres", 3)
3426 .Case("hwr_ulr", 29)
3432 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3434 if (Name[0] == 'f') {
3435 StringRef NumString = Name.substr(1);
3437 if (NumString.getAsInteger(10, IntVal))
3438 return -1; // This is not an integer.
3439 if (IntVal > 31) // Maximum index for fpu register.
3446 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3448 if (Name.startswith("fcc")) {
3449 StringRef NumString = Name.substr(3);
3451 if (NumString.getAsInteger(10, IntVal))
3452 return -1; // This is not an integer.
3453 if (IntVal > 7) // There are only 8 fcc registers.
3460 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3462 if (Name.startswith("ac")) {
3463 StringRef NumString = Name.substr(2);
3465 if (NumString.getAsInteger(10, IntVal))
3466 return -1; // This is not an integer.
3467 if (IntVal > 3) // There are only 3 acc registers.
3474 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3477 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3486 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3489 CC = StringSwitch<unsigned>(Name)
3492 .Case("msaaccess", 2)
3494 .Case("msamodify", 4)
3495 .Case("msarequest", 5)
3497 .Case("msaunmap", 7)
3503 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3504 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3506 reportParseError(Loc,
3507 "pseudo-instruction requires $at, which is not available");
3510 unsigned AT = getReg(
3511 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3515 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3516 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3519 unsigned MipsAsmParser::getGPR(int RegNo) {
3520 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3524 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3526 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3529 return getReg(RegClass, RegNum);
3532 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3533 MCAsmParser &Parser = getParser();
3534 DEBUG(dbgs() << "parseOperand\n");
3536 // Check if the current operand has a custom associated parser, if so, try to
3537 // custom parse the operand, or fallback to the general approach.
3538 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3539 if (ResTy == MatchOperand_Success)
3541 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3542 // there was a match, but an error occurred, in which case, just return that
3543 // the operand parsing failed.
3544 if (ResTy == MatchOperand_ParseFail)
3547 DEBUG(dbgs() << ".. Generic Parser\n");
3549 switch (getLexer().getKind()) {
3551 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3553 case AsmToken::Dollar: {
3554 // Parse the register.
3555 SMLoc S = Parser.getTok().getLoc();
3557 // Almost all registers have been parsed by custom parsers. There is only
3558 // one exception to this. $zero (and it's alias $0) will reach this point
3559 // for div, divu, and similar instructions because it is not an operand
3560 // to the instruction definition but an explicit register. Special case
3561 // this situation for now.
3562 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3565 // Maybe it is a symbol reference.
3566 StringRef Identifier;
3567 if (Parser.parseIdentifier(Identifier))
3570 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3571 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3572 // Otherwise create a symbol reference.
3574 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3576 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3579 // Else drop to expression parsing.
3580 case AsmToken::LParen:
3581 case AsmToken::Minus:
3582 case AsmToken::Plus:
3583 case AsmToken::Integer:
3584 case AsmToken::Tilde:
3585 case AsmToken::String: {
3586 DEBUG(dbgs() << ".. generic integer\n");
3587 OperandMatchResultTy ResTy = parseImm(Operands);
3588 return ResTy != MatchOperand_Success;
3590 case AsmToken::Percent: {
3591 // It is a symbol reference or constant expression.
3592 const MCExpr *IdVal;
3593 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3594 if (parseRelocOperand(IdVal))
3597 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3599 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3601 } // case AsmToken::Percent
3602 } // switch(getLexer().getKind())
3606 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3607 StringRef RelocStr) {
3609 // Check the type of the expression.
3610 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3611 // It's a constant, evaluate reloc value.
3613 switch (getVariantKind(RelocStr)) {
3614 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3615 // Get the 1st 16-bits.
3616 Val = MCE->getValue() & 0xffff;
3618 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3619 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3620 // 16 bits being negative.
3621 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3623 case MCSymbolRefExpr::VK_Mips_HIGHER:
3624 // Get the 3rd 16-bits.
3625 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3627 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3628 // Get the 4th 16-bits.
3629 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3632 report_fatal_error("unsupported reloc value");
3634 return MCConstantExpr::create(Val, getContext());
3637 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3638 // It's a symbol, create a symbolic expression from the symbol.
3639 const MCSymbol *Symbol = &MSRE->getSymbol();
3640 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3641 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3645 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3646 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3648 // Try to create target expression.
3649 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3650 return MipsMCExpr::create(VK, Expr, getContext());
3652 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3653 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3654 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3658 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3659 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3660 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3663 // Just return the original expression.
3667 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3669 switch (Expr->getKind()) {
3670 case MCExpr::Constant:
3672 case MCExpr::SymbolRef:
3673 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3674 case MCExpr::Binary:
3675 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3676 if (!isEvaluated(BE->getLHS()))
3678 return isEvaluated(BE->getRHS());
3681 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3682 case MCExpr::Target:
3688 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3689 MCAsmParser &Parser = getParser();
3690 Parser.Lex(); // Eat the % token.
3691 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3692 if (Tok.isNot(AsmToken::Identifier))
3695 std::string Str = Tok.getIdentifier();
3697 Parser.Lex(); // Eat the identifier.
3698 // Now make an expression from the rest of the operand.
3699 const MCExpr *IdVal;
3702 if (getLexer().getKind() == AsmToken::LParen) {
3704 Parser.Lex(); // Eat the '(' token.
3705 if (getLexer().getKind() == AsmToken::Percent) {
3706 Parser.Lex(); // Eat the % token.
3707 const AsmToken &nextTok = Parser.getTok();
3708 if (nextTok.isNot(AsmToken::Identifier))
3711 Str += nextTok.getIdentifier();
3712 Parser.Lex(); // Eat the identifier.
3713 if (getLexer().getKind() != AsmToken::LParen)
3718 if (getParser().parseParenExpression(IdVal, EndLoc))
3721 while (getLexer().getKind() == AsmToken::RParen)
3722 Parser.Lex(); // Eat the ')' token.
3725 return true; // Parenthesis must follow the relocation operand.
3727 Res = evaluateRelocExpr(IdVal, Str);
3731 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3733 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3734 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3735 if (ResTy == MatchOperand_Success) {
3736 assert(Operands.size() == 1);
3737 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3738 StartLoc = Operand.getStartLoc();
3739 EndLoc = Operand.getEndLoc();
3741 // AFAIK, we only support numeric registers and named GPR's in CFI
3743 // Don't worry about eating tokens before failing. Using an unrecognised
3744 // register is a parse error.
3745 if (Operand.isGPRAsmReg()) {
3746 // Resolve to GPR32 or GPR64 appropriately.
3747 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3750 return (RegNo == (unsigned)-1);
3753 assert(Operands.size() == 0);
3754 return (RegNo == (unsigned)-1);
3757 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3758 MCAsmParser &Parser = getParser();
3761 unsigned NumOfLParen = 0;
3763 while (getLexer().getKind() == AsmToken::LParen) {
3768 switch (getLexer().getKind()) {
3771 case AsmToken::Identifier:
3772 case AsmToken::LParen:
3773 case AsmToken::Integer:
3774 case AsmToken::Minus:
3775 case AsmToken::Plus:
3777 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3779 Result = (getParser().parseExpression(Res));
3780 while (getLexer().getKind() == AsmToken::RParen)
3783 case AsmToken::Percent:
3784 Result = parseRelocOperand(Res);
3789 MipsAsmParser::OperandMatchResultTy
3790 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3791 MCAsmParser &Parser = getParser();
3792 DEBUG(dbgs() << "parseMemOperand\n");
3793 const MCExpr *IdVal = nullptr;
3795 bool isParenExpr = false;
3796 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3797 // First operand is the offset.
3798 S = Parser.getTok().getLoc();
3800 if (getLexer().getKind() == AsmToken::LParen) {
3805 if (getLexer().getKind() != AsmToken::Dollar) {
3806 if (parseMemOffset(IdVal, isParenExpr))
3807 return MatchOperand_ParseFail;
3809 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3810 if (Tok.isNot(AsmToken::LParen)) {
3811 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3812 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3814 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3815 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3816 return MatchOperand_Success;
3818 if (Tok.is(AsmToken::EndOfStatement)) {
3820 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3822 // Zero register assumed, add a memory operand with ZERO as its base.
3823 // "Base" will be managed by k_Memory.
3824 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3827 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3828 return MatchOperand_Success;
3830 Error(Parser.getTok().getLoc(), "'(' expected");
3831 return MatchOperand_ParseFail;
3834 Parser.Lex(); // Eat the '(' token.
3837 Res = parseAnyRegister(Operands);
3838 if (Res != MatchOperand_Success)
3841 if (Parser.getTok().isNot(AsmToken::RParen)) {
3842 Error(Parser.getTok().getLoc(), "')' expected");
3843 return MatchOperand_ParseFail;
3846 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3848 Parser.Lex(); // Eat the ')' token.
3851 IdVal = MCConstantExpr::create(0, getContext());
3853 // Replace the register operand with the memory operand.
3854 std::unique_ptr<MipsOperand> op(
3855 static_cast<MipsOperand *>(Operands.back().release()));
3856 // Remove the register from the operands.
3857 // "op" will be managed by k_Memory.
3858 Operands.pop_back();
3859 // Add the memory operand.
3860 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3862 if (IdVal->evaluateAsAbsolute(Imm))
3863 IdVal = MCConstantExpr::create(Imm, getContext());
3864 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3865 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3869 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3870 return MatchOperand_Success;
3873 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3874 MCAsmParser &Parser = getParser();
3875 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3877 SMLoc S = Parser.getTok().getLoc();
3879 if (Sym->isVariable())
3880 Expr = Sym->getVariableValue();
3883 if (Expr->getKind() == MCExpr::SymbolRef) {
3884 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3885 StringRef DefSymbol = Ref->getSymbol().getName();
3886 if (DefSymbol.startswith("$")) {
3887 OperandMatchResultTy ResTy =
3888 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3889 if (ResTy == MatchOperand_Success) {
3892 } else if (ResTy == MatchOperand_ParseFail)
3893 llvm_unreachable("Should never ParseFail");
3896 } else if (Expr->getKind() == MCExpr::Constant) {
3898 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3900 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3907 MipsAsmParser::OperandMatchResultTy
3908 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3909 StringRef Identifier,
3911 int Index = matchCPURegisterName(Identifier);
3913 Operands.push_back(MipsOperand::createGPRReg(
3914 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3915 return MatchOperand_Success;
3918 Index = matchHWRegsRegisterName(Identifier);
3920 Operands.push_back(MipsOperand::createHWRegsReg(
3921 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3922 return MatchOperand_Success;
3925 Index = matchFPURegisterName(Identifier);
3927 Operands.push_back(MipsOperand::createFGRReg(
3928 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3929 return MatchOperand_Success;
3932 Index = matchFCCRegisterName(Identifier);
3934 Operands.push_back(MipsOperand::createFCCReg(
3935 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3936 return MatchOperand_Success;
3939 Index = matchACRegisterName(Identifier);
3941 Operands.push_back(MipsOperand::createACCReg(
3942 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3943 return MatchOperand_Success;
3946 Index = matchMSA128RegisterName(Identifier);
3948 Operands.push_back(MipsOperand::createMSA128Reg(
3949 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3950 return MatchOperand_Success;
3953 Index = matchMSA128CtrlRegisterName(Identifier);
3955 Operands.push_back(MipsOperand::createMSACtrlReg(
3956 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3957 return MatchOperand_Success;
3960 return MatchOperand_NoMatch;
3963 MipsAsmParser::OperandMatchResultTy
3964 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3965 MCAsmParser &Parser = getParser();
3966 auto Token = Parser.getLexer().peekTok(false);
3968 if (Token.is(AsmToken::Identifier)) {
3969 DEBUG(dbgs() << ".. identifier\n");
3970 StringRef Identifier = Token.getIdentifier();
3971 OperandMatchResultTy ResTy =
3972 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3974 } else if (Token.is(AsmToken::Integer)) {
3975 DEBUG(dbgs() << ".. integer\n");
3976 Operands.push_back(MipsOperand::createNumericReg(
3977 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3979 return MatchOperand_Success;
3982 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3984 return MatchOperand_NoMatch;
3987 MipsAsmParser::OperandMatchResultTy
3988 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3989 MCAsmParser &Parser = getParser();
3990 DEBUG(dbgs() << "parseAnyRegister\n");
3992 auto Token = Parser.getTok();
3994 SMLoc S = Token.getLoc();
3996 if (Token.isNot(AsmToken::Dollar)) {
3997 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3998 if (Token.is(AsmToken::Identifier)) {
3999 if (searchSymbolAlias(Operands))
4000 return MatchOperand_Success;
4002 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4003 return MatchOperand_NoMatch;
4005 DEBUG(dbgs() << ".. $\n");
4007 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4008 if (ResTy == MatchOperand_Success) {
4010 Parser.Lex(); // identifier
4015 MipsAsmParser::OperandMatchResultTy
4016 MipsAsmParser::parseImm(OperandVector &Operands) {
4017 MCAsmParser &Parser = getParser();
4018 switch (getLexer().getKind()) {
4020 return MatchOperand_NoMatch;
4021 case AsmToken::LParen:
4022 case AsmToken::Minus:
4023 case AsmToken::Plus:
4024 case AsmToken::Integer:
4025 case AsmToken::Tilde:
4026 case AsmToken::String:
4030 const MCExpr *IdVal;
4031 SMLoc S = Parser.getTok().getLoc();
4032 if (getParser().parseExpression(IdVal))
4033 return MatchOperand_ParseFail;
4035 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4036 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4037 return MatchOperand_Success;
4040 MipsAsmParser::OperandMatchResultTy
4041 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4042 MCAsmParser &Parser = getParser();
4043 DEBUG(dbgs() << "parseJumpTarget\n");
4045 SMLoc S = getLexer().getLoc();
4047 // Integers and expressions are acceptable
4048 OperandMatchResultTy ResTy = parseImm(Operands);
4049 if (ResTy != MatchOperand_NoMatch)
4052 // Registers are a valid target and have priority over symbols.
4053 ResTy = parseAnyRegister(Operands);
4054 if (ResTy != MatchOperand_NoMatch)
4057 const MCExpr *Expr = nullptr;
4058 if (Parser.parseExpression(Expr)) {
4059 // We have no way of knowing if a symbol was consumed so we must ParseFail
4060 return MatchOperand_ParseFail;
4063 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4064 return MatchOperand_Success;
4067 MipsAsmParser::OperandMatchResultTy
4068 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4069 MCAsmParser &Parser = getParser();
4070 const MCExpr *IdVal;
4071 // If the first token is '$' we may have register operand.
4072 if (Parser.getTok().is(AsmToken::Dollar))
4073 return MatchOperand_NoMatch;
4074 SMLoc S = Parser.getTok().getLoc();
4075 if (getParser().parseExpression(IdVal))
4076 return MatchOperand_ParseFail;
4077 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4078 assert(MCE && "Unexpected MCExpr type.");
4079 int64_t Val = MCE->getValue();
4080 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4081 Operands.push_back(MipsOperand::CreateImm(
4082 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4083 return MatchOperand_Success;
4086 MipsAsmParser::OperandMatchResultTy
4087 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4088 MCAsmParser &Parser = getParser();
4089 switch (getLexer().getKind()) {
4091 return MatchOperand_NoMatch;
4092 case AsmToken::LParen:
4093 case AsmToken::Plus:
4094 case AsmToken::Minus:
4095 case AsmToken::Integer:
4100 SMLoc S = Parser.getTok().getLoc();
4102 if (getParser().parseExpression(Expr))
4103 return MatchOperand_ParseFail;
4106 if (!Expr->evaluateAsAbsolute(Val)) {
4107 Error(S, "expected immediate value");
4108 return MatchOperand_ParseFail;
4111 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4112 // and because the CPU always adds one to the immediate field, the allowed
4113 // range becomes 1..4. We'll only check the range here and will deal
4114 // with the addition/subtraction when actually decoding/encoding
4116 if (Val < 1 || Val > 4) {
4117 Error(S, "immediate not in range (1..4)");
4118 return MatchOperand_ParseFail;
4122 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4123 return MatchOperand_Success;
4126 MipsAsmParser::OperandMatchResultTy
4127 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4128 MCAsmParser &Parser = getParser();
4129 SmallVector<unsigned, 10> Regs;
4131 unsigned PrevReg = Mips::NoRegister;
4132 bool RegRange = false;
4133 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4135 if (Parser.getTok().isNot(AsmToken::Dollar))
4136 return MatchOperand_ParseFail;
4138 SMLoc S = Parser.getTok().getLoc();
4139 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4140 SMLoc E = getLexer().getLoc();
4141 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4142 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4144 // Remove last register operand because registers from register range
4145 // should be inserted first.
4146 if (RegNo == Mips::RA) {
4147 Regs.push_back(RegNo);
4149 unsigned TmpReg = PrevReg + 1;
4150 while (TmpReg <= RegNo) {
4151 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4152 Error(E, "invalid register operand");
4153 return MatchOperand_ParseFail;
4157 Regs.push_back(TmpReg++);
4163 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4164 (RegNo != Mips::RA)) {
4165 Error(E, "$16 or $31 expected");
4166 return MatchOperand_ParseFail;
4167 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4168 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4169 Error(E, "invalid register operand");
4170 return MatchOperand_ParseFail;
4171 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4172 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4173 Error(E, "consecutive register numbers expected");
4174 return MatchOperand_ParseFail;
4177 Regs.push_back(RegNo);
4180 if (Parser.getTok().is(AsmToken::Minus))
4183 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4184 !Parser.getTok().isNot(AsmToken::Comma)) {
4185 Error(E, "',' or '-' expected");
4186 return MatchOperand_ParseFail;
4189 Lex(); // Consume comma or minus
4190 if (Parser.getTok().isNot(AsmToken::Dollar))
4196 SMLoc E = Parser.getTok().getLoc();
4197 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4198 parseMemOperand(Operands);
4199 return MatchOperand_Success;
4202 MipsAsmParser::OperandMatchResultTy
4203 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4204 MCAsmParser &Parser = getParser();
4206 SMLoc S = Parser.getTok().getLoc();
4207 if (parseAnyRegister(Operands) != MatchOperand_Success)
4208 return MatchOperand_ParseFail;
4210 SMLoc E = Parser.getTok().getLoc();
4211 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4212 unsigned Reg = Op.getGPR32Reg();
4213 Operands.pop_back();
4214 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4215 return MatchOperand_Success;
4218 MipsAsmParser::OperandMatchResultTy
4219 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4220 MCAsmParser &Parser = getParser();
4221 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4222 SmallVector<unsigned, 10> Regs;
4224 if (Parser.getTok().isNot(AsmToken::Dollar))
4225 return MatchOperand_ParseFail;
4227 SMLoc S = Parser.getTok().getLoc();
4229 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4230 return MatchOperand_ParseFail;
4232 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4233 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4234 Regs.push_back(RegNo);
4236 SMLoc E = Parser.getTok().getLoc();
4237 if (Parser.getTok().isNot(AsmToken::Comma)) {
4238 Error(E, "',' expected");
4239 return MatchOperand_ParseFail;
4245 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4246 return MatchOperand_ParseFail;
4248 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4249 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4250 Regs.push_back(RegNo);
4252 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4254 return MatchOperand_Success;
4257 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4259 MCSymbolRefExpr::VariantKind VK =
4260 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4261 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4262 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4263 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4264 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4265 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4266 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4267 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4268 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4269 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4270 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4271 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4272 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4273 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4274 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4275 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4276 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4277 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4278 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4279 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4280 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4281 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4282 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4283 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4284 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4285 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4286 .Default(MCSymbolRefExpr::VK_None);
4288 assert(VK != MCSymbolRefExpr::VK_None);
4293 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4295 /// ::= '(', register, ')'
4296 /// handle it before we iterate so we don't get tripped up by the lack of
4298 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4299 MCAsmParser &Parser = getParser();
4300 if (getLexer().is(AsmToken::LParen)) {
4302 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4304 if (parseOperand(Operands, Name)) {
4305 SMLoc Loc = getLexer().getLoc();
4306 Parser.eatToEndOfStatement();
4307 return Error(Loc, "unexpected token in argument list");
4309 if (Parser.getTok().isNot(AsmToken::RParen)) {
4310 SMLoc Loc = getLexer().getLoc();
4311 Parser.eatToEndOfStatement();
4312 return Error(Loc, "unexpected token, expected ')'");
4315 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4321 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4322 /// either one of these.
4323 /// ::= '[', register, ']'
4324 /// ::= '[', integer, ']'
4325 /// handle it before we iterate so we don't get tripped up by the lack of
4327 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4328 OperandVector &Operands) {
4329 MCAsmParser &Parser = getParser();
4330 if (getLexer().is(AsmToken::LBrac)) {
4332 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4334 if (parseOperand(Operands, Name)) {
4335 SMLoc Loc = getLexer().getLoc();
4336 Parser.eatToEndOfStatement();
4337 return Error(Loc, "unexpected token in argument list");
4339 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4340 SMLoc Loc = getLexer().getLoc();
4341 Parser.eatToEndOfStatement();
4342 return Error(Loc, "unexpected token, expected ']'");
4345 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4351 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4352 SMLoc NameLoc, OperandVector &Operands) {
4353 MCAsmParser &Parser = getParser();
4354 DEBUG(dbgs() << "ParseInstruction\n");
4356 // We have reached first instruction, module directive are now forbidden.
4357 getTargetStreamer().forbidModuleDirective();
4359 // Check if we have valid mnemonic
4360 if (!mnemonicIsValid(Name, 0)) {
4361 Parser.eatToEndOfStatement();
4362 return Error(NameLoc, "unknown instruction");
4364 // First operand in MCInst is instruction mnemonic.
4365 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4367 // Read the remaining operands.
4368 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4369 // Read the first operand.
4370 if (parseOperand(Operands, Name)) {
4371 SMLoc Loc = getLexer().getLoc();
4372 Parser.eatToEndOfStatement();
4373 return Error(Loc, "unexpected token in argument list");
4375 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4377 // AFAIK, parenthesis suffixes are never on the first operand
4379 while (getLexer().is(AsmToken::Comma)) {
4380 Parser.Lex(); // Eat the comma.
4381 // Parse and remember the operand.
4382 if (parseOperand(Operands, Name)) {
4383 SMLoc Loc = getLexer().getLoc();
4384 Parser.eatToEndOfStatement();
4385 return Error(Loc, "unexpected token in argument list");
4387 // Parse bracket and parenthesis suffixes before we iterate
4388 if (getLexer().is(AsmToken::LBrac)) {
4389 if (parseBracketSuffix(Name, Operands))
4391 } else if (getLexer().is(AsmToken::LParen) &&
4392 parseParenSuffix(Name, Operands))
4396 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4397 SMLoc Loc = getLexer().getLoc();
4398 Parser.eatToEndOfStatement();
4399 return Error(Loc, "unexpected token in argument list");
4401 Parser.Lex(); // Consume the EndOfStatement.
4405 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4406 MCAsmParser &Parser = getParser();
4407 SMLoc Loc = getLexer().getLoc();
4408 Parser.eatToEndOfStatement();
4409 return Error(Loc, ErrorMsg);
4412 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4413 return Error(Loc, ErrorMsg);
4416 bool MipsAsmParser::parseSetNoAtDirective() {
4417 MCAsmParser &Parser = getParser();
4418 // Line should look like: ".set noat".
4420 // Set the $at register to $0.
4421 AssemblerOptions.back()->setATRegIndex(0);
4423 Parser.Lex(); // Eat "noat".
4425 // If this is not the end of the statement, report an error.
4426 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4427 reportParseError("unexpected token, expected end of statement");
4431 getTargetStreamer().emitDirectiveSetNoAt();
4432 Parser.Lex(); // Consume the EndOfStatement.
4436 bool MipsAsmParser::parseSetAtDirective() {
4437 // Line can be: ".set at", which sets $at to $1
4438 // or ".set at=$reg", which sets $at to $reg.
4439 MCAsmParser &Parser = getParser();
4440 Parser.Lex(); // Eat "at".
4442 if (getLexer().is(AsmToken::EndOfStatement)) {
4443 // No register was specified, so we set $at to $1.
4444 AssemblerOptions.back()->setATRegIndex(1);
4446 getTargetStreamer().emitDirectiveSetAt();
4447 Parser.Lex(); // Consume the EndOfStatement.
4451 if (getLexer().isNot(AsmToken::Equal)) {
4452 reportParseError("unexpected token, expected equals sign");
4455 Parser.Lex(); // Eat "=".
4457 if (getLexer().isNot(AsmToken::Dollar)) {
4458 if (getLexer().is(AsmToken::EndOfStatement)) {
4459 reportParseError("no register specified");
4462 reportParseError("unexpected token, expected dollar sign '$'");
4466 Parser.Lex(); // Eat "$".
4468 // Find out what "reg" is.
4470 const AsmToken &Reg = Parser.getTok();
4471 if (Reg.is(AsmToken::Identifier)) {
4472 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4473 } else if (Reg.is(AsmToken::Integer)) {
4474 AtRegNo = Reg.getIntVal();
4476 reportParseError("unexpected token, expected identifier or integer");
4480 // Check if $reg is a valid register. If it is, set $at to $reg.
4481 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4482 reportParseError("invalid register");
4485 Parser.Lex(); // Eat "reg".
4487 // If this is not the end of the statement, report an error.
4488 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4489 reportParseError("unexpected token, expected end of statement");
4493 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4495 Parser.Lex(); // Consume the EndOfStatement.
4499 bool MipsAsmParser::parseSetReorderDirective() {
4500 MCAsmParser &Parser = getParser();
4502 // If this is not the end of the statement, report an error.
4503 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4504 reportParseError("unexpected token, expected end of statement");
4507 AssemblerOptions.back()->setReorder();
4508 getTargetStreamer().emitDirectiveSetReorder();
4509 Parser.Lex(); // Consume the EndOfStatement.
4513 bool MipsAsmParser::parseSetNoReorderDirective() {
4514 MCAsmParser &Parser = getParser();
4516 // If this is not the end of the statement, report an error.
4517 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4518 reportParseError("unexpected token, expected end of statement");
4521 AssemblerOptions.back()->setNoReorder();
4522 getTargetStreamer().emitDirectiveSetNoReorder();
4523 Parser.Lex(); // Consume the EndOfStatement.
4527 bool MipsAsmParser::parseSetMacroDirective() {
4528 MCAsmParser &Parser = getParser();
4530 // If this is not the end of the statement, report an error.
4531 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4532 reportParseError("unexpected token, expected end of statement");
4535 AssemblerOptions.back()->setMacro();
4536 getTargetStreamer().emitDirectiveSetMacro();
4537 Parser.Lex(); // Consume the EndOfStatement.
4541 bool MipsAsmParser::parseSetNoMacroDirective() {
4542 MCAsmParser &Parser = getParser();
4544 // If this is not the end of the statement, report an error.
4545 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4546 reportParseError("unexpected token, expected end of statement");
4549 if (AssemblerOptions.back()->isReorder()) {
4550 reportParseError("`noreorder' must be set before `nomacro'");
4553 AssemblerOptions.back()->setNoMacro();
4554 getTargetStreamer().emitDirectiveSetNoMacro();
4555 Parser.Lex(); // Consume the EndOfStatement.
4559 bool MipsAsmParser::parseSetMsaDirective() {
4560 MCAsmParser &Parser = getParser();
4563 // If this is not the end of the statement, report an error.
4564 if (getLexer().isNot(AsmToken::EndOfStatement))
4565 return reportParseError("unexpected token, expected end of statement");
4567 setFeatureBits(Mips::FeatureMSA, "msa");
4568 getTargetStreamer().emitDirectiveSetMsa();
4572 bool MipsAsmParser::parseSetNoMsaDirective() {
4573 MCAsmParser &Parser = getParser();
4576 // If this is not the end of the statement, report an error.
4577 if (getLexer().isNot(AsmToken::EndOfStatement))
4578 return reportParseError("unexpected token, expected end of statement");
4580 clearFeatureBits(Mips::FeatureMSA, "msa");
4581 getTargetStreamer().emitDirectiveSetNoMsa();
4585 bool MipsAsmParser::parseSetNoDspDirective() {
4586 MCAsmParser &Parser = getParser();
4587 Parser.Lex(); // Eat "nodsp".
4589 // If this is not the end of the statement, report an error.
4590 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4591 reportParseError("unexpected token, expected end of statement");
4595 clearFeatureBits(Mips::FeatureDSP, "dsp");
4596 getTargetStreamer().emitDirectiveSetNoDsp();
4600 bool MipsAsmParser::parseSetMips16Directive() {
4601 MCAsmParser &Parser = getParser();
4602 Parser.Lex(); // Eat "mips16".
4604 // If this is not the end of the statement, report an error.
4605 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4606 reportParseError("unexpected token, expected end of statement");
4610 setFeatureBits(Mips::FeatureMips16, "mips16");
4611 getTargetStreamer().emitDirectiveSetMips16();
4612 Parser.Lex(); // Consume the EndOfStatement.
4616 bool MipsAsmParser::parseSetNoMips16Directive() {
4617 MCAsmParser &Parser = getParser();
4618 Parser.Lex(); // Eat "nomips16".
4620 // If this is not the end of the statement, report an error.
4621 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4622 reportParseError("unexpected token, expected end of statement");
4626 clearFeatureBits(Mips::FeatureMips16, "mips16");
4627 getTargetStreamer().emitDirectiveSetNoMips16();
4628 Parser.Lex(); // Consume the EndOfStatement.
4632 bool MipsAsmParser::parseSetFpDirective() {
4633 MCAsmParser &Parser = getParser();
4634 MipsABIFlagsSection::FpABIKind FpAbiVal;
4635 // Line can be: .set fp=32
4638 Parser.Lex(); // Eat fp token
4639 AsmToken Tok = Parser.getTok();
4640 if (Tok.isNot(AsmToken::Equal)) {
4641 reportParseError("unexpected token, expected equals sign '='");
4644 Parser.Lex(); // Eat '=' token.
4645 Tok = Parser.getTok();
4647 if (!parseFpABIValue(FpAbiVal, ".set"))
4650 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4651 reportParseError("unexpected token, expected end of statement");
4654 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4655 Parser.Lex(); // Consume the EndOfStatement.
4659 bool MipsAsmParser::parseSetOddSPRegDirective() {
4660 MCAsmParser &Parser = getParser();
4662 Parser.Lex(); // Eat "oddspreg".
4663 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4664 reportParseError("unexpected token, expected end of statement");
4668 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4669 getTargetStreamer().emitDirectiveSetOddSPReg();
4673 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4674 MCAsmParser &Parser = getParser();
4676 Parser.Lex(); // Eat "nooddspreg".
4677 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4678 reportParseError("unexpected token, expected end of statement");
4682 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4683 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4687 bool MipsAsmParser::parseSetPopDirective() {
4688 MCAsmParser &Parser = getParser();
4689 SMLoc Loc = getLexer().getLoc();
4692 if (getLexer().isNot(AsmToken::EndOfStatement))
4693 return reportParseError("unexpected token, expected end of statement");
4695 // Always keep an element on the options "stack" to prevent the user
4696 // from changing the initial options. This is how we remember them.
4697 if (AssemblerOptions.size() == 2)
4698 return reportParseError(Loc, ".set pop with no .set push");
4700 AssemblerOptions.pop_back();
4701 setAvailableFeatures(
4702 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4703 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4705 getTargetStreamer().emitDirectiveSetPop();
4709 bool MipsAsmParser::parseSetPushDirective() {
4710 MCAsmParser &Parser = getParser();
4712 if (getLexer().isNot(AsmToken::EndOfStatement))
4713 return reportParseError("unexpected token, expected end of statement");
4715 // Create a copy of the current assembler options environment and push it.
4716 AssemblerOptions.push_back(
4717 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4719 getTargetStreamer().emitDirectiveSetPush();
4723 bool MipsAsmParser::parseSetSoftFloatDirective() {
4724 MCAsmParser &Parser = getParser();
4726 if (getLexer().isNot(AsmToken::EndOfStatement))
4727 return reportParseError("unexpected token, expected end of statement");
4729 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4730 getTargetStreamer().emitDirectiveSetSoftFloat();
4734 bool MipsAsmParser::parseSetHardFloatDirective() {
4735 MCAsmParser &Parser = getParser();
4737 if (getLexer().isNot(AsmToken::EndOfStatement))
4738 return reportParseError("unexpected token, expected end of statement");
4740 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4741 getTargetStreamer().emitDirectiveSetHardFloat();
4745 bool MipsAsmParser::parseSetAssignment() {
4747 const MCExpr *Value;
4748 MCAsmParser &Parser = getParser();
4750 if (Parser.parseIdentifier(Name))
4751 reportParseError("expected identifier after .set");
4753 if (getLexer().isNot(AsmToken::Comma))
4754 return reportParseError("unexpected token, expected comma");
4757 if (Parser.parseExpression(Value))
4758 return reportParseError("expected valid expression after comma");
4760 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4761 Sym->setVariableValue(Value);
4766 bool MipsAsmParser::parseSetMips0Directive() {
4767 MCAsmParser &Parser = getParser();
4769 if (getLexer().isNot(AsmToken::EndOfStatement))
4770 return reportParseError("unexpected token, expected end of statement");
4772 // Reset assembler options to their initial values.
4773 setAvailableFeatures(
4774 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4775 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4776 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4778 getTargetStreamer().emitDirectiveSetMips0();
4782 bool MipsAsmParser::parseSetArchDirective() {
4783 MCAsmParser &Parser = getParser();
4785 if (getLexer().isNot(AsmToken::Equal))
4786 return reportParseError("unexpected token, expected equals sign");
4790 if (Parser.parseIdentifier(Arch))
4791 return reportParseError("expected arch identifier");
4793 StringRef ArchFeatureName =
4794 StringSwitch<StringRef>(Arch)
4795 .Case("mips1", "mips1")
4796 .Case("mips2", "mips2")
4797 .Case("mips3", "mips3")
4798 .Case("mips4", "mips4")
4799 .Case("mips5", "mips5")
4800 .Case("mips32", "mips32")
4801 .Case("mips32r2", "mips32r2")
4802 .Case("mips32r3", "mips32r3")
4803 .Case("mips32r5", "mips32r5")
4804 .Case("mips32r6", "mips32r6")
4805 .Case("mips64", "mips64")
4806 .Case("mips64r2", "mips64r2")
4807 .Case("mips64r3", "mips64r3")
4808 .Case("mips64r5", "mips64r5")
4809 .Case("mips64r6", "mips64r6")
4810 .Case("cnmips", "cnmips")
4811 .Case("r4000", "mips3") // This is an implementation of Mips3.
4814 if (ArchFeatureName.empty())
4815 return reportParseError("unsupported architecture");
4817 selectArch(ArchFeatureName);
4818 getTargetStreamer().emitDirectiveSetArch(Arch);
4822 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4823 MCAsmParser &Parser = getParser();
4825 if (getLexer().isNot(AsmToken::EndOfStatement))
4826 return reportParseError("unexpected token, expected end of statement");
4830 llvm_unreachable("Unimplemented feature");
4831 case Mips::FeatureDSP:
4832 setFeatureBits(Mips::FeatureDSP, "dsp");
4833 getTargetStreamer().emitDirectiveSetDsp();
4835 case Mips::FeatureMicroMips:
4836 getTargetStreamer().emitDirectiveSetMicroMips();
4838 case Mips::FeatureMips1:
4839 selectArch("mips1");
4840 getTargetStreamer().emitDirectiveSetMips1();
4842 case Mips::FeatureMips2:
4843 selectArch("mips2");
4844 getTargetStreamer().emitDirectiveSetMips2();
4846 case Mips::FeatureMips3:
4847 selectArch("mips3");
4848 getTargetStreamer().emitDirectiveSetMips3();
4850 case Mips::FeatureMips4:
4851 selectArch("mips4");
4852 getTargetStreamer().emitDirectiveSetMips4();
4854 case Mips::FeatureMips5:
4855 selectArch("mips5");
4856 getTargetStreamer().emitDirectiveSetMips5();
4858 case Mips::FeatureMips32:
4859 selectArch("mips32");
4860 getTargetStreamer().emitDirectiveSetMips32();
4862 case Mips::FeatureMips32r2:
4863 selectArch("mips32r2");
4864 getTargetStreamer().emitDirectiveSetMips32R2();
4866 case Mips::FeatureMips32r3:
4867 selectArch("mips32r3");
4868 getTargetStreamer().emitDirectiveSetMips32R3();
4870 case Mips::FeatureMips32r5:
4871 selectArch("mips32r5");
4872 getTargetStreamer().emitDirectiveSetMips32R5();
4874 case Mips::FeatureMips32r6:
4875 selectArch("mips32r6");
4876 getTargetStreamer().emitDirectiveSetMips32R6();
4878 case Mips::FeatureMips64:
4879 selectArch("mips64");
4880 getTargetStreamer().emitDirectiveSetMips64();
4882 case Mips::FeatureMips64r2:
4883 selectArch("mips64r2");
4884 getTargetStreamer().emitDirectiveSetMips64R2();
4886 case Mips::FeatureMips64r3:
4887 selectArch("mips64r3");
4888 getTargetStreamer().emitDirectiveSetMips64R3();
4890 case Mips::FeatureMips64r5:
4891 selectArch("mips64r5");
4892 getTargetStreamer().emitDirectiveSetMips64R5();
4894 case Mips::FeatureMips64r6:
4895 selectArch("mips64r6");
4896 getTargetStreamer().emitDirectiveSetMips64R6();
4902 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4903 MCAsmParser &Parser = getParser();
4904 if (getLexer().isNot(AsmToken::Comma)) {
4905 SMLoc Loc = getLexer().getLoc();
4906 Parser.eatToEndOfStatement();
4907 return Error(Loc, ErrorStr);
4910 Parser.Lex(); // Eat the comma.
4914 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4915 // In this class, it is only used for .cprestore.
4916 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4917 // MipsTargetELFStreamer and MipsAsmParser.
4918 bool MipsAsmParser::isPicAndNotNxxAbi() {
4919 return inPicMode() && !(isABI_N32() || isABI_N64());
4922 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4923 if (AssemblerOptions.back()->isReorder())
4924 Warning(Loc, ".cpload should be inside a noreorder section");
4926 if (inMips16Mode()) {
4927 reportParseError(".cpload is not supported in Mips16 mode");
4931 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4932 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4933 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4934 reportParseError("expected register containing function address");
4938 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4939 if (!RegOpnd.isGPRAsmReg()) {
4940 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4944 // If this is not the end of the statement, report an error.
4945 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4946 reportParseError("unexpected token, expected end of statement");
4950 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4954 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4955 MCAsmParser &Parser = getParser();
4957 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4958 // is used in non-PIC mode.
4960 if (inMips16Mode()) {
4961 reportParseError(".cprestore is not supported in Mips16 mode");
4965 // Get the stack offset value.
4966 const MCExpr *StackOffset;
4967 int64_t StackOffsetVal;
4968 if (Parser.parseExpression(StackOffset)) {
4969 reportParseError("expected stack offset value");
4973 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4974 reportParseError("stack offset is not an absolute expression");
4978 if (StackOffsetVal < 0) {
4979 Warning(Loc, ".cprestore with negative stack offset has no effect");
4980 IsCpRestoreSet = false;
4982 IsCpRestoreSet = true;
4983 CpRestoreOffset = StackOffsetVal;
4986 // If this is not the end of the statement, report an error.
4987 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4988 reportParseError("unexpected token, expected end of statement");
4992 // Store the $gp on the stack.
4993 SmallVector<MCInst, 3> StoreInsts;
4994 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
4997 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
4998 Parser.Lex(); // Consume the EndOfStatement.
5002 bool MipsAsmParser::parseDirectiveCPSetup() {
5003 MCAsmParser &Parser = getParser();
5006 bool SaveIsReg = true;
5008 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5009 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5010 if (ResTy == MatchOperand_NoMatch) {
5011 reportParseError("expected register containing function address");
5012 Parser.eatToEndOfStatement();
5016 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5017 if (!FuncRegOpnd.isGPRAsmReg()) {
5018 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5019 Parser.eatToEndOfStatement();
5023 FuncReg = FuncRegOpnd.getGPR32Reg();
5026 if (!eatComma("unexpected token, expected comma"))
5029 ResTy = parseAnyRegister(TmpReg);
5030 if (ResTy == MatchOperand_NoMatch) {
5031 const MCExpr *OffsetExpr;
5033 SMLoc ExprLoc = getLexer().getLoc();
5035 if (Parser.parseExpression(OffsetExpr) ||
5036 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5037 reportParseError(ExprLoc, "expected save register or stack offset");
5038 Parser.eatToEndOfStatement();
5045 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5046 if (!SaveOpnd.isGPRAsmReg()) {
5047 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5048 Parser.eatToEndOfStatement();
5051 Save = SaveOpnd.getGPR32Reg();
5054 if (!eatComma("unexpected token, expected comma"))
5058 if (Parser.parseExpression(Expr)) {
5059 reportParseError("expected expression");
5063 if (Expr->getKind() != MCExpr::SymbolRef) {
5064 reportParseError("expected symbol");
5067 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5069 CpSaveLocation = Save;
5070 CpSaveLocationIsRegister = SaveIsReg;
5072 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5077 bool MipsAsmParser::parseDirectiveCPReturn() {
5078 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5079 CpSaveLocationIsRegister);
5083 bool MipsAsmParser::parseDirectiveNaN() {
5084 MCAsmParser &Parser = getParser();
5085 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5086 const AsmToken &Tok = Parser.getTok();
5088 if (Tok.getString() == "2008") {
5090 getTargetStreamer().emitDirectiveNaN2008();
5092 } else if (Tok.getString() == "legacy") {
5094 getTargetStreamer().emitDirectiveNaNLegacy();
5098 // If we don't recognize the option passed to the .nan
5099 // directive (e.g. no option or unknown option), emit an error.
5100 reportParseError("invalid option in .nan directive");
5104 bool MipsAsmParser::parseDirectiveSet() {
5105 MCAsmParser &Parser = getParser();
5106 // Get the next token.
5107 const AsmToken &Tok = Parser.getTok();
5109 if (Tok.getString() == "noat") {
5110 return parseSetNoAtDirective();
5111 } else if (Tok.getString() == "at") {
5112 return parseSetAtDirective();
5113 } else if (Tok.getString() == "arch") {
5114 return parseSetArchDirective();
5115 } else if (Tok.getString() == "fp") {
5116 return parseSetFpDirective();
5117 } else if (Tok.getString() == "oddspreg") {
5118 return parseSetOddSPRegDirective();
5119 } else if (Tok.getString() == "nooddspreg") {
5120 return parseSetNoOddSPRegDirective();
5121 } else if (Tok.getString() == "pop") {
5122 return parseSetPopDirective();
5123 } else if (Tok.getString() == "push") {
5124 return parseSetPushDirective();
5125 } else if (Tok.getString() == "reorder") {
5126 return parseSetReorderDirective();
5127 } else if (Tok.getString() == "noreorder") {
5128 return parseSetNoReorderDirective();
5129 } else if (Tok.getString() == "macro") {
5130 return parseSetMacroDirective();
5131 } else if (Tok.getString() == "nomacro") {
5132 return parseSetNoMacroDirective();
5133 } else if (Tok.getString() == "mips16") {
5134 return parseSetMips16Directive();
5135 } else if (Tok.getString() == "nomips16") {
5136 return parseSetNoMips16Directive();
5137 } else if (Tok.getString() == "nomicromips") {
5138 getTargetStreamer().emitDirectiveSetNoMicroMips();
5139 Parser.eatToEndOfStatement();
5141 } else if (Tok.getString() == "micromips") {
5142 return parseSetFeature(Mips::FeatureMicroMips);
5143 } else if (Tok.getString() == "mips0") {
5144 return parseSetMips0Directive();
5145 } else if (Tok.getString() == "mips1") {
5146 return parseSetFeature(Mips::FeatureMips1);
5147 } else if (Tok.getString() == "mips2") {
5148 return parseSetFeature(Mips::FeatureMips2);
5149 } else if (Tok.getString() == "mips3") {
5150 return parseSetFeature(Mips::FeatureMips3);
5151 } else if (Tok.getString() == "mips4") {
5152 return parseSetFeature(Mips::FeatureMips4);
5153 } else if (Tok.getString() == "mips5") {
5154 return parseSetFeature(Mips::FeatureMips5);
5155 } else if (Tok.getString() == "mips32") {
5156 return parseSetFeature(Mips::FeatureMips32);
5157 } else if (Tok.getString() == "mips32r2") {
5158 return parseSetFeature(Mips::FeatureMips32r2);
5159 } else if (Tok.getString() == "mips32r3") {
5160 return parseSetFeature(Mips::FeatureMips32r3);
5161 } else if (Tok.getString() == "mips32r5") {
5162 return parseSetFeature(Mips::FeatureMips32r5);
5163 } else if (Tok.getString() == "mips32r6") {
5164 return parseSetFeature(Mips::FeatureMips32r6);
5165 } else if (Tok.getString() == "mips64") {
5166 return parseSetFeature(Mips::FeatureMips64);
5167 } else if (Tok.getString() == "mips64r2") {
5168 return parseSetFeature(Mips::FeatureMips64r2);
5169 } else if (Tok.getString() == "mips64r3") {
5170 return parseSetFeature(Mips::FeatureMips64r3);
5171 } else if (Tok.getString() == "mips64r5") {
5172 return parseSetFeature(Mips::FeatureMips64r5);
5173 } else if (Tok.getString() == "mips64r6") {
5174 return parseSetFeature(Mips::FeatureMips64r6);
5175 } else if (Tok.getString() == "dsp") {
5176 return parseSetFeature(Mips::FeatureDSP);
5177 } else if (Tok.getString() == "nodsp") {
5178 return parseSetNoDspDirective();
5179 } else if (Tok.getString() == "msa") {
5180 return parseSetMsaDirective();
5181 } else if (Tok.getString() == "nomsa") {
5182 return parseSetNoMsaDirective();
5183 } else if (Tok.getString() == "softfloat") {
5184 return parseSetSoftFloatDirective();
5185 } else if (Tok.getString() == "hardfloat") {
5186 return parseSetHardFloatDirective();
5188 // It is just an identifier, look for an assignment.
5189 parseSetAssignment();
5196 /// parseDataDirective
5197 /// ::= .word [ expression (, expression)* ]
5198 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5199 MCAsmParser &Parser = getParser();
5200 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5202 const MCExpr *Value;
5203 if (getParser().parseExpression(Value))
5206 getParser().getStreamer().EmitValue(Value, Size);
5208 if (getLexer().is(AsmToken::EndOfStatement))
5211 if (getLexer().isNot(AsmToken::Comma))
5212 return Error(L, "unexpected token, expected comma");
5221 /// parseDirectiveGpWord
5222 /// ::= .gpword local_sym
5223 bool MipsAsmParser::parseDirectiveGpWord() {
5224 MCAsmParser &Parser = getParser();
5225 const MCExpr *Value;
5226 // EmitGPRel32Value requires an expression, so we are using base class
5227 // method to evaluate the expression.
5228 if (getParser().parseExpression(Value))
5230 getParser().getStreamer().EmitGPRel32Value(Value);
5232 if (getLexer().isNot(AsmToken::EndOfStatement))
5233 return Error(getLexer().getLoc(),
5234 "unexpected token, expected end of statement");
5235 Parser.Lex(); // Eat EndOfStatement token.
5239 /// parseDirectiveGpDWord
5240 /// ::= .gpdword local_sym
5241 bool MipsAsmParser::parseDirectiveGpDWord() {
5242 MCAsmParser &Parser = getParser();
5243 const MCExpr *Value;
5244 // EmitGPRel64Value requires an expression, so we are using base class
5245 // method to evaluate the expression.
5246 if (getParser().parseExpression(Value))
5248 getParser().getStreamer().EmitGPRel64Value(Value);
5250 if (getLexer().isNot(AsmToken::EndOfStatement))
5251 return Error(getLexer().getLoc(),
5252 "unexpected token, expected end of statement");
5253 Parser.Lex(); // Eat EndOfStatement token.
5257 bool MipsAsmParser::parseDirectiveOption() {
5258 MCAsmParser &Parser = getParser();
5259 // Get the option token.
5260 AsmToken Tok = Parser.getTok();
5261 // At the moment only identifiers are supported.
5262 if (Tok.isNot(AsmToken::Identifier)) {
5263 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5264 Parser.eatToEndOfStatement();
5268 StringRef Option = Tok.getIdentifier();
5270 if (Option == "pic0") {
5271 // MipsAsmParser needs to know if the current PIC mode changes.
5272 IsPicEnabled = false;
5274 getTargetStreamer().emitDirectiveOptionPic0();
5276 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5277 Error(Parser.getTok().getLoc(),
5278 "unexpected token, expected end of statement");
5279 Parser.eatToEndOfStatement();
5284 if (Option == "pic2") {
5285 // MipsAsmParser needs to know if the current PIC mode changes.
5286 IsPicEnabled = true;
5288 getTargetStreamer().emitDirectiveOptionPic2();
5290 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5291 Error(Parser.getTok().getLoc(),
5292 "unexpected token, expected end of statement");
5293 Parser.eatToEndOfStatement();
5299 Warning(Parser.getTok().getLoc(),
5300 "unknown option, expected 'pic0' or 'pic2'");
5301 Parser.eatToEndOfStatement();
5305 /// parseInsnDirective
5307 bool MipsAsmParser::parseInsnDirective() {
5308 // If this is not the end of the statement, report an error.
5309 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5310 reportParseError("unexpected token, expected end of statement");
5314 // The actual label marking happens in
5315 // MipsELFStreamer::createPendingLabelRelocs().
5316 getTargetStreamer().emitDirectiveInsn();
5318 getParser().Lex(); // Eat EndOfStatement token.
5322 /// parseDirectiveModule
5323 /// ::= .module oddspreg
5324 /// ::= .module nooddspreg
5325 /// ::= .module fp=value
5326 /// ::= .module softfloat
5327 /// ::= .module hardfloat
5328 bool MipsAsmParser::parseDirectiveModule() {
5329 MCAsmParser &Parser = getParser();
5330 MCAsmLexer &Lexer = getLexer();
5331 SMLoc L = Lexer.getLoc();
5333 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5334 // TODO : get a better message.
5335 reportParseError(".module directive must appear before any code");
5340 if (Parser.parseIdentifier(Option)) {
5341 reportParseError("expected .module option identifier");
5345 if (Option == "oddspreg") {
5346 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5348 // Synchronize the abiflags information with the FeatureBits information we
5350 getTargetStreamer().updateABIInfo(*this);
5352 // If printing assembly, use the recently updated abiflags information.
5353 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5354 // emitted at the end).
5355 getTargetStreamer().emitDirectiveModuleOddSPReg();
5357 // If this is not the end of the statement, report an error.
5358 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5359 reportParseError("unexpected token, expected end of statement");
5363 return false; // parseDirectiveModule has finished successfully.
5364 } else if (Option == "nooddspreg") {
5366 Error(L, "'.module nooddspreg' requires the O32 ABI");
5370 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5372 // Synchronize the abiflags information with the FeatureBits information we
5374 getTargetStreamer().updateABIInfo(*this);
5376 // If printing assembly, use the recently updated abiflags information.
5377 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5378 // emitted at the end).
5379 getTargetStreamer().emitDirectiveModuleOddSPReg();
5381 // If this is not the end of the statement, report an error.
5382 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5383 reportParseError("unexpected token, expected end of statement");
5387 return false; // parseDirectiveModule has finished successfully.
5388 } else if (Option == "fp") {
5389 return parseDirectiveModuleFP();
5390 } else if (Option == "softfloat") {
5391 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5393 // Synchronize the ABI Flags information with the FeatureBits information we
5395 getTargetStreamer().updateABIInfo(*this);
5397 // If printing assembly, use the recently updated ABI Flags information.
5398 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5400 getTargetStreamer().emitDirectiveModuleSoftFloat();
5402 // If this is not the end of the statement, report an error.
5403 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5404 reportParseError("unexpected token, expected end of statement");
5408 return false; // parseDirectiveModule has finished successfully.
5409 } else if (Option == "hardfloat") {
5410 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5412 // Synchronize the ABI Flags information with the FeatureBits information we
5414 getTargetStreamer().updateABIInfo(*this);
5416 // If printing assembly, use the recently updated ABI Flags information.
5417 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5419 getTargetStreamer().emitDirectiveModuleHardFloat();
5421 // If this is not the end of the statement, report an error.
5422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5423 reportParseError("unexpected token, expected end of statement");
5427 return false; // parseDirectiveModule has finished successfully.
5429 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5433 /// parseDirectiveModuleFP
5437 bool MipsAsmParser::parseDirectiveModuleFP() {
5438 MCAsmParser &Parser = getParser();
5439 MCAsmLexer &Lexer = getLexer();
5441 if (Lexer.isNot(AsmToken::Equal)) {
5442 reportParseError("unexpected token, expected equals sign '='");
5445 Parser.Lex(); // Eat '=' token.
5447 MipsABIFlagsSection::FpABIKind FpABI;
5448 if (!parseFpABIValue(FpABI, ".module"))
5451 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5452 reportParseError("unexpected token, expected end of statement");
5456 // Synchronize the abiflags information with the FeatureBits information we
5458 getTargetStreamer().updateABIInfo(*this);
5460 // If printing assembly, use the recently updated abiflags information.
5461 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5462 // emitted at the end).
5463 getTargetStreamer().emitDirectiveModuleFP();
5465 Parser.Lex(); // Consume the EndOfStatement.
5469 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5470 StringRef Directive) {
5471 MCAsmParser &Parser = getParser();
5472 MCAsmLexer &Lexer = getLexer();
5473 bool ModuleLevelOptions = Directive == ".module";
5475 if (Lexer.is(AsmToken::Identifier)) {
5476 StringRef Value = Parser.getTok().getString();
5479 if (Value != "xx") {
5480 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5485 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5489 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5490 if (ModuleLevelOptions) {
5491 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5492 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5494 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5495 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5500 if (Lexer.is(AsmToken::Integer)) {
5501 unsigned Value = Parser.getTok().getIntVal();
5504 if (Value != 32 && Value != 64) {
5505 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5511 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5515 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5516 if (ModuleLevelOptions) {
5517 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5518 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5520 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5521 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5524 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5525 if (ModuleLevelOptions) {
5526 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5527 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5529 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5530 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5540 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5541 MCAsmParser &Parser = getParser();
5542 StringRef IDVal = DirectiveID.getString();
5544 if (IDVal == ".cpload")
5545 return parseDirectiveCpLoad(DirectiveID.getLoc());
5546 if (IDVal == ".cprestore")
5547 return parseDirectiveCpRestore(DirectiveID.getLoc());
5548 if (IDVal == ".dword") {
5549 parseDataDirective(8, DirectiveID.getLoc());
5552 if (IDVal == ".ent") {
5553 StringRef SymbolName;
5555 if (Parser.parseIdentifier(SymbolName)) {
5556 reportParseError("expected identifier after .ent");
5560 // There's an undocumented extension that allows an integer to
5561 // follow the name of the procedure which AFAICS is ignored by GAS.
5562 // Example: .ent foo,2
5563 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5564 if (getLexer().isNot(AsmToken::Comma)) {
5565 // Even though we accept this undocumented extension for compatibility
5566 // reasons, the additional integer argument does not actually change
5567 // the behaviour of the '.ent' directive, so we would like to discourage
5568 // its use. We do this by not referring to the extended version in
5569 // error messages which are not directly related to its use.
5570 reportParseError("unexpected token, expected end of statement");
5573 Parser.Lex(); // Eat the comma.
5574 const MCExpr *DummyNumber;
5575 int64_t DummyNumberVal;
5576 // If the user was explicitly trying to use the extended version,
5577 // we still give helpful extension-related error messages.
5578 if (Parser.parseExpression(DummyNumber)) {
5579 reportParseError("expected number after comma");
5582 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5583 reportParseError("expected an absolute expression after comma");
5588 // If this is not the end of the statement, report an error.
5589 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5590 reportParseError("unexpected token, expected end of statement");
5594 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5596 getTargetStreamer().emitDirectiveEnt(*Sym);
5598 IsCpRestoreSet = false;
5602 if (IDVal == ".end") {
5603 StringRef SymbolName;
5605 if (Parser.parseIdentifier(SymbolName)) {
5606 reportParseError("expected identifier after .end");
5610 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5611 reportParseError("unexpected token, expected end of statement");
5615 if (CurrentFn == nullptr) {
5616 reportParseError(".end used without .ent");
5620 if ((SymbolName != CurrentFn->getName())) {
5621 reportParseError(".end symbol does not match .ent symbol");
5625 getTargetStreamer().emitDirectiveEnd(SymbolName);
5626 CurrentFn = nullptr;
5627 IsCpRestoreSet = false;
5631 if (IDVal == ".frame") {
5632 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5633 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5634 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5635 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5636 reportParseError("expected stack register");
5640 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5641 if (!StackRegOpnd.isGPRAsmReg()) {
5642 reportParseError(StackRegOpnd.getStartLoc(),
5643 "expected general purpose register");
5646 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5648 if (Parser.getTok().is(AsmToken::Comma))
5651 reportParseError("unexpected token, expected comma");
5655 // Parse the frame size.
5656 const MCExpr *FrameSize;
5657 int64_t FrameSizeVal;
5659 if (Parser.parseExpression(FrameSize)) {
5660 reportParseError("expected frame size value");
5664 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5665 reportParseError("frame size not an absolute expression");
5669 if (Parser.getTok().is(AsmToken::Comma))
5672 reportParseError("unexpected token, expected comma");
5676 // Parse the return register.
5678 ResTy = parseAnyRegister(TmpReg);
5679 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5680 reportParseError("expected return register");
5684 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5685 if (!ReturnRegOpnd.isGPRAsmReg()) {
5686 reportParseError(ReturnRegOpnd.getStartLoc(),
5687 "expected general purpose register");
5691 // If this is not the end of the statement, report an error.
5692 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5693 reportParseError("unexpected token, expected end of statement");
5697 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5698 ReturnRegOpnd.getGPR32Reg());
5699 IsCpRestoreSet = false;
5703 if (IDVal == ".set") {
5704 return parseDirectiveSet();
5707 if (IDVal == ".mask" || IDVal == ".fmask") {
5708 // .mask bitmask, frame_offset
5709 // bitmask: One bit for each register used.
5710 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5711 // first register is expected to be saved.
5713 // .mask 0x80000000, -4
5714 // .fmask 0x80000000, -4
5717 // Parse the bitmask
5718 const MCExpr *BitMask;
5721 if (Parser.parseExpression(BitMask)) {
5722 reportParseError("expected bitmask value");
5726 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5727 reportParseError("bitmask not an absolute expression");
5731 if (Parser.getTok().is(AsmToken::Comma))
5734 reportParseError("unexpected token, expected comma");
5738 // Parse the frame_offset
5739 const MCExpr *FrameOffset;
5740 int64_t FrameOffsetVal;
5742 if (Parser.parseExpression(FrameOffset)) {
5743 reportParseError("expected frame offset value");
5747 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5748 reportParseError("frame offset not an absolute expression");
5752 // If this is not the end of the statement, report an error.
5753 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5754 reportParseError("unexpected token, expected end of statement");
5758 if (IDVal == ".mask")
5759 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5761 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5765 if (IDVal == ".nan")
5766 return parseDirectiveNaN();
5768 if (IDVal == ".gpword") {
5769 parseDirectiveGpWord();
5773 if (IDVal == ".gpdword") {
5774 parseDirectiveGpDWord();
5778 if (IDVal == ".word") {
5779 parseDataDirective(4, DirectiveID.getLoc());
5783 if (IDVal == ".option")
5784 return parseDirectiveOption();
5786 if (IDVal == ".abicalls") {
5787 getTargetStreamer().emitDirectiveAbiCalls();
5788 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5789 Error(Parser.getTok().getLoc(),
5790 "unexpected token, expected end of statement");
5792 Parser.eatToEndOfStatement();
5797 if (IDVal == ".cpsetup")
5798 return parseDirectiveCPSetup();
5800 if (IDVal == ".cpreturn")
5801 return parseDirectiveCPReturn();
5803 if (IDVal == ".module")
5804 return parseDirectiveModule();
5806 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5807 return parseInternalDirectiveReallowModule();
5809 if (IDVal == ".insn")
5810 return parseInsnDirective();
5815 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5816 // If this is not the end of the statement, report an error.
5817 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5818 reportParseError("unexpected token, expected end of statement");
5822 getTargetStreamer().reallowModuleDirective();
5824 getParser().Lex(); // Eat EndOfStatement token.
5828 extern "C" void LLVMInitializeMipsAsmParser() {
5829 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5830 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5831 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5832 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5835 #define GET_REGISTER_MATCHER
5836 #define GET_MATCHER_IMPLEMENTATION
5837 #include "MipsGenAsmMatcher.inc"