1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCParser/MCAsmLexer.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCTargetAsmParser.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
38 #define DEBUG_TYPE "mips-asm-parser"
45 class MipsAssemblerOptions {
47 MipsAssemblerOptions(const FeatureBitset &Features_) :
48 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
50 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
51 ATReg = Opts->getATRegIndex();
52 Reorder = Opts->isReorder();
53 Macro = Opts->isMacro();
54 Features = Opts->getFeatures();
57 unsigned getATRegIndex() const { return ATReg; }
58 bool setATRegIndex(unsigned Reg) {
66 bool isReorder() const { return Reorder; }
67 void setReorder() { Reorder = true; }
68 void setNoReorder() { Reorder = false; }
70 bool isMacro() const { return Macro; }
71 void setMacro() { Macro = true; }
72 void setNoMacro() { Macro = false; }
74 const FeatureBitset &getFeatures() const { return Features; }
75 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
77 // Set of features that are either architecture features or referenced
78 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
79 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
80 // The reason we need this mask is explained in the selectArch function.
81 // FIXME: Ideally we would like TableGen to generate this information.
82 static const FeatureBitset AllArchRelatedMask;
88 FeatureBitset Features;
92 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
93 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
94 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
95 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
96 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
97 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
98 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
99 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
100 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
104 class MipsAsmParser : public MCTargetAsmParser {
105 MipsTargetStreamer &getTargetStreamer() {
106 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
107 return static_cast<MipsTargetStreamer &>(TS);
110 MCSubtargetInfo &STI;
112 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
113 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
114 // nullptr, which indicates that no function is currently
115 // selected. This usually happens after an '.end func'
121 unsigned CpSaveLocation;
122 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
123 bool CpSaveLocationIsRegister;
125 // Print a warning along with its fix-it message at the given range.
126 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
127 SMRange Range, bool ShowColors = true);
129 #define GET_ASSEMBLER_HEADER
130 #include "MipsGenAsmMatcher.inc"
132 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
134 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
135 OperandVector &Operands, MCStreamer &Out,
137 bool MatchingInlineAsm) override;
139 /// Parse a register as used in CFI directives
140 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
142 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
144 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
146 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
147 SMLoc NameLoc, OperandVector &Operands) override;
149 bool ParseDirective(AsmToken DirectiveID) override;
151 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
153 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
154 StringRef Identifier, SMLoc S);
155 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
157 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
158 OperandMatchResultTy parseImm(OperandVector &Operands);
159 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
160 OperandMatchResultTy parseInvNum(OperandVector &Operands);
161 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
163 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
164 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
166 bool searchSymbolAlias(OperandVector &Operands);
168 bool parseOperand(OperandVector &, StringRef Mnemonic);
170 bool needsExpansion(MCInst &Inst);
172 // Expands assembly pseudo instructions.
173 // Returns false on success, true otherwise.
174 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
175 SmallVectorImpl<MCInst> &Instructions);
177 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
178 SmallVectorImpl<MCInst> &Instructions);
180 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
181 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
182 SmallVectorImpl<MCInst> &Instructions);
184 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
185 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
191 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
192 const MCOperand &Offset, bool Is32BitAddress,
193 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
195 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions);
198 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
199 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
202 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions);
205 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions);
208 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
215 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
218 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions);
221 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
222 SmallVectorImpl<MCInst> &Instructions);
224 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
225 SmallVectorImpl<MCInst> &Instructions);
227 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
228 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
230 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
231 SmallVectorImpl<MCInst> &Instructions);
233 bool reportParseError(Twine ErrorMsg);
234 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
236 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
237 bool parseRelocOperand(const MCExpr *&Res);
239 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
241 bool isEvaluated(const MCExpr *Expr);
242 bool parseSetMips0Directive();
243 bool parseSetArchDirective();
244 bool parseSetFeature(uint64_t Feature);
245 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
246 bool parseDirectiveCpLoad(SMLoc Loc);
247 bool parseDirectiveCpRestore(SMLoc Loc);
248 bool parseDirectiveCPSetup();
249 bool parseDirectiveCPReturn();
250 bool parseDirectiveNaN();
251 bool parseDirectiveSet();
252 bool parseDirectiveOption();
253 bool parseInsnDirective();
255 bool parseSetAtDirective();
256 bool parseSetNoAtDirective();
257 bool parseSetMacroDirective();
258 bool parseSetNoMacroDirective();
259 bool parseSetMsaDirective();
260 bool parseSetNoMsaDirective();
261 bool parseSetNoDspDirective();
262 bool parseSetReorderDirective();
263 bool parseSetNoReorderDirective();
264 bool parseSetMips16Directive();
265 bool parseSetNoMips16Directive();
266 bool parseSetFpDirective();
267 bool parseSetOddSPRegDirective();
268 bool parseSetNoOddSPRegDirective();
269 bool parseSetPopDirective();
270 bool parseSetPushDirective();
271 bool parseSetSoftFloatDirective();
272 bool parseSetHardFloatDirective();
274 bool parseSetAssignment();
276 bool parseDataDirective(unsigned Size, SMLoc L);
277 bool parseDirectiveGpWord();
278 bool parseDirectiveGpDWord();
279 bool parseDirectiveModule();
280 bool parseDirectiveModuleFP();
281 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
282 StringRef Directive);
284 bool parseInternalDirectiveReallowModule();
286 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
288 bool eatComma(StringRef ErrorStr);
290 int matchCPURegisterName(StringRef Symbol);
292 int matchHWRegsRegisterName(StringRef Symbol);
294 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
296 int matchFPURegisterName(StringRef Name);
298 int matchFCCRegisterName(StringRef Name);
300 int matchACRegisterName(StringRef Name);
302 int matchMSA128RegisterName(StringRef Name);
304 int matchMSA128CtrlRegisterName(StringRef Name);
306 unsigned getReg(int RC, int RegNo);
308 unsigned getGPR(int RegNo);
310 /// Returns the internal register number for the current AT. Also checks if
311 /// the current AT is unavailable (set to $0) and gives an error if it is.
312 /// This should be used in pseudo-instruction expansions which need AT.
313 unsigned getATReg(SMLoc Loc);
315 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
316 SmallVectorImpl<MCInst> &Instructions);
318 // Helper function that checks if the value of a vector index is within the
319 // boundaries of accepted values for each RegisterKind
320 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
321 bool validateMSAIndex(int Val, int RegKind);
323 // Selects a new architecture by updating the FeatureBits with the necessary
324 // info including implied dependencies.
325 // Internally, it clears all the feature bits related to *any* architecture
326 // and selects the new one using the ToggleFeature functionality of the
327 // MCSubtargetInfo object that handles implied dependencies. The reason we
328 // clear all the arch related bits manually is because ToggleFeature only
329 // clears the features that imply the feature being cleared and not the
330 // features implied by the feature being cleared. This is easier to see
332 // --------------------------------------------------
333 // | Feature | Implies |
334 // | -------------------------------------------------|
335 // | FeatureMips1 | None |
336 // | FeatureMips2 | FeatureMips1 |
337 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
338 // | FeatureMips4 | FeatureMips3 |
340 // --------------------------------------------------
342 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
343 // FeatureMipsGP64 | FeatureMips1)
344 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
345 void selectArch(StringRef ArchFeature) {
346 FeatureBitset FeatureBits = STI.getFeatureBits();
347 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
348 STI.setFeatureBits(FeatureBits);
349 setAvailableFeatures(
350 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
351 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
354 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
355 if (!(STI.getFeatureBits()[Feature])) {
356 setAvailableFeatures(
357 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
358 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
362 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
363 if (STI.getFeatureBits()[Feature]) {
364 setAvailableFeatures(
365 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
366 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
370 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
371 setFeatureBits(Feature, FeatureString);
372 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
375 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
376 clearFeatureBits(Feature, FeatureString);
377 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
381 enum MipsMatchResultTy {
382 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
383 #define GET_OPERAND_DIAGNOSTIC_TYPES
384 #include "MipsGenAsmMatcher.inc"
385 #undef GET_OPERAND_DIAGNOSTIC_TYPES
389 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
390 const MCInstrInfo &MII, const MCTargetOptions &Options)
391 : MCTargetAsmParser(Options), STI(sti),
392 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
393 sti.getCPU(), Options)) {
394 MCAsmParserExtension::Initialize(parser);
396 parser.addAliasForDirective(".asciiz", ".asciz");
398 // Initialize the set of available features.
399 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
401 // Remember the initial assembler options. The user can not modify these.
402 AssemblerOptions.push_back(
403 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
405 // Create an assembler options environment for the user to modify.
406 AssemblerOptions.push_back(
407 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
409 getTargetStreamer().updateABIInfo(*this);
411 if (!isABI_O32() && !useOddSPReg() != 0)
412 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
417 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
419 IsCpRestoreSet = false;
420 CpRestoreOffset = -1;
422 Triple TheTriple(sti.getTargetTriple());
423 if ((TheTriple.getArch() == Triple::mips) ||
424 (TheTriple.getArch() == Triple::mips64))
425 IsLittleEndian = false;
427 IsLittleEndian = true;
430 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
431 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
433 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
434 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
435 const MipsABIInfo &getABI() const { return ABI; }
436 bool isABI_N32() const { return ABI.IsN32(); }
437 bool isABI_N64() const { return ABI.IsN64(); }
438 bool isABI_O32() const { return ABI.IsO32(); }
439 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
441 bool useOddSPReg() const {
442 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
445 bool inMicroMipsMode() const {
446 return STI.getFeatureBits()[Mips::FeatureMicroMips];
448 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
449 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
450 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
451 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
452 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
453 bool hasMips32() const {
454 return STI.getFeatureBits()[Mips::FeatureMips32];
456 bool hasMips64() const {
457 return STI.getFeatureBits()[Mips::FeatureMips64];
459 bool hasMips32r2() const {
460 return STI.getFeatureBits()[Mips::FeatureMips32r2];
462 bool hasMips64r2() const {
463 return STI.getFeatureBits()[Mips::FeatureMips64r2];
465 bool hasMips32r3() const {
466 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
468 bool hasMips64r3() const {
469 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
471 bool hasMips32r5() const {
472 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
474 bool hasMips64r5() const {
475 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
477 bool hasMips32r6() const {
478 return STI.getFeatureBits()[Mips::FeatureMips32r6];
480 bool hasMips64r6() const {
481 return STI.getFeatureBits()[Mips::FeatureMips64r6];
484 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
485 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
486 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
487 bool hasCnMips() const {
488 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
495 bool inMips16Mode() const {
496 return STI.getFeatureBits()[Mips::FeatureMips16];
499 bool useTraps() const {
500 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
503 bool useSoftFloat() const {
504 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
507 /// Warn if RegIndex is the same as the current AT.
508 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
510 void warnIfNoMacro(SMLoc Loc);
512 bool isLittle() const { return IsLittleEndian; }
518 /// MipsOperand - Instances of this class represent a parsed Mips machine
520 class MipsOperand : public MCParsedAsmOperand {
522 /// Broad categories of register classes
523 /// The exact class is finalized by the render method.
525 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
526 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
528 RegKind_FCC = 4, /// FCC
529 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
530 RegKind_MSACtrl = 16, /// MSA control registers
531 RegKind_COP2 = 32, /// COP2
532 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
534 RegKind_CCR = 128, /// CCR
535 RegKind_HWRegs = 256, /// HWRegs
536 RegKind_COP3 = 512, /// COP3
537 RegKind_COP0 = 1024, /// COP0
538 /// Potentially any (e.g. $1)
539 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
540 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
541 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
546 k_Immediate, /// An immediate (possibly involving symbol references)
547 k_Memory, /// Base + Offset Memory Address
548 k_PhysRegister, /// A physical register from the Mips namespace
549 k_RegisterIndex, /// A register index in one or more RegKind.
550 k_Token, /// A simple token
551 k_RegList, /// A physical register list
552 k_RegPair /// A pair of physical register
556 MipsOperand(KindTy K, MipsAsmParser &Parser)
557 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
560 /// For diagnostics, and checking the assembler temporary
561 MipsAsmParser &AsmParser;
569 unsigned Num; /// Register Number
573 unsigned Index; /// Index into the register class
574 RegKind Kind; /// Bitfield of the kinds it could possibly be
575 const MCRegisterInfo *RegInfo;
588 SmallVector<unsigned, 10> *List;
593 struct PhysRegOp PhysReg;
594 struct RegIdxOp RegIdx;
597 struct RegListOp RegList;
600 SMLoc StartLoc, EndLoc;
602 /// Internal constructor for register kinds
603 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
604 const MCRegisterInfo *RegInfo,
606 MipsAsmParser &Parser) {
607 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
608 Op->RegIdx.Index = Index;
609 Op->RegIdx.RegInfo = RegInfo;
610 Op->RegIdx.Kind = RegKind;
617 /// Coerce the register to GPR32 and return the real register for the current
619 unsigned getGPR32Reg() const {
620 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
621 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
622 unsigned ClassID = Mips::GPR32RegClassID;
623 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
626 /// Coerce the register to GPR32 and return the real register for the current
628 unsigned getGPRMM16Reg() const {
629 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
630 unsigned ClassID = Mips::GPR32RegClassID;
631 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
634 /// Coerce the register to GPR64 and return the real register for the current
636 unsigned getGPR64Reg() const {
637 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
638 unsigned ClassID = Mips::GPR64RegClassID;
639 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
643 /// Coerce the register to AFGR64 and return the real register for the current
645 unsigned getAFGR64Reg() const {
646 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
647 if (RegIdx.Index % 2 != 0)
648 AsmParser.Warning(StartLoc, "Float register should be even.");
649 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
650 .getRegister(RegIdx.Index / 2);
653 /// Coerce the register to FGR64 and return the real register for the current
655 unsigned getFGR64Reg() const {
656 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
657 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
658 .getRegister(RegIdx.Index);
661 /// Coerce the register to FGR32 and return the real register for the current
663 unsigned getFGR32Reg() const {
664 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
665 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
666 .getRegister(RegIdx.Index);
669 /// Coerce the register to FGRH32 and return the real register for the current
671 unsigned getFGRH32Reg() const {
672 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
673 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
674 .getRegister(RegIdx.Index);
677 /// Coerce the register to FCC and return the real register for the current
679 unsigned getFCCReg() const {
680 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
681 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
682 .getRegister(RegIdx.Index);
685 /// Coerce the register to MSA128 and return the real register for the current
687 unsigned getMSA128Reg() const {
688 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
689 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
691 unsigned ClassID = Mips::MSA128BRegClassID;
692 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
695 /// Coerce the register to MSACtrl and return the real register for the
697 unsigned getMSACtrlReg() const {
698 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
699 unsigned ClassID = Mips::MSACtrlRegClassID;
700 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
703 /// Coerce the register to COP0 and return the real register for the
705 unsigned getCOP0Reg() const {
706 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
707 unsigned ClassID = Mips::COP0RegClassID;
708 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
711 /// Coerce the register to COP2 and return the real register for the
713 unsigned getCOP2Reg() const {
714 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
715 unsigned ClassID = Mips::COP2RegClassID;
716 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
719 /// Coerce the register to COP3 and return the real register for the
721 unsigned getCOP3Reg() const {
722 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
723 unsigned ClassID = Mips::COP3RegClassID;
724 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
727 /// Coerce the register to ACC64DSP and return the real register for the
729 unsigned getACC64DSPReg() const {
730 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
731 unsigned ClassID = Mips::ACC64DSPRegClassID;
732 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
735 /// Coerce the register to HI32DSP and return the real register for the
737 unsigned getHI32DSPReg() const {
738 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
739 unsigned ClassID = Mips::HI32DSPRegClassID;
740 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
743 /// Coerce the register to LO32DSP and return the real register for the
745 unsigned getLO32DSPReg() const {
746 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
747 unsigned ClassID = Mips::LO32DSPRegClassID;
748 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
751 /// Coerce the register to CCR and return the real register for the
753 unsigned getCCRReg() const {
754 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
755 unsigned ClassID = Mips::CCRRegClassID;
756 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
759 /// Coerce the register to HWRegs and return the real register for the
761 unsigned getHWRegsReg() const {
762 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
763 unsigned ClassID = Mips::HWRegsRegClassID;
764 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
768 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
769 // Add as immediate when possible. Null MCExpr = 0.
771 Inst.addOperand(MCOperand::createImm(0));
772 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
773 Inst.addOperand(MCOperand::createImm(CE->getValue()));
775 Inst.addOperand(MCOperand::createExpr(Expr));
778 void addRegOperands(MCInst &Inst, unsigned N) const {
779 llvm_unreachable("Use a custom parser instead");
782 /// Render the operand to an MCInst as a GPR32
783 /// Asserts if the wrong number of operands are requested, or the operand
784 /// is not a k_RegisterIndex compatible with RegKind_GPR
785 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
786 assert(N == 1 && "Invalid number of operands!");
787 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
790 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
791 assert(N == 1 && "Invalid number of operands!");
792 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
795 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
796 assert(N == 1 && "Invalid number of operands!");
797 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
800 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
801 assert(N == 1 && "Invalid number of operands!");
802 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
805 /// Render the operand to an MCInst as a GPR64
806 /// Asserts if the wrong number of operands are requested, or the operand
807 /// is not a k_RegisterIndex compatible with RegKind_GPR
808 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
809 assert(N == 1 && "Invalid number of operands!");
810 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
813 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 1 && "Invalid number of operands!");
815 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
818 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
819 assert(N == 1 && "Invalid number of operands!");
820 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
823 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
824 assert(N == 1 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
826 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
827 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
828 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
832 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
833 assert(N == 1 && "Invalid number of operands!");
834 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
837 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
838 assert(N == 1 && "Invalid number of operands!");
839 Inst.addOperand(MCOperand::createReg(getFCCReg()));
842 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
843 assert(N == 1 && "Invalid number of operands!");
844 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
847 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 1 && "Invalid number of operands!");
849 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
852 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
853 assert(N == 1 && "Invalid number of operands!");
854 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
857 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
858 assert(N == 1 && "Invalid number of operands!");
859 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
862 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
863 assert(N == 1 && "Invalid number of operands!");
864 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
867 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
868 assert(N == 1 && "Invalid number of operands!");
869 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
872 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
873 assert(N == 1 && "Invalid number of operands!");
874 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
877 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
878 assert(N == 1 && "Invalid number of operands!");
879 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
882 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
883 assert(N == 1 && "Invalid number of operands!");
884 Inst.addOperand(MCOperand::createReg(getCCRReg()));
887 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
888 assert(N == 1 && "Invalid number of operands!");
889 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
892 void addImmOperands(MCInst &Inst, unsigned N) const {
893 assert(N == 1 && "Invalid number of operands!");
894 const MCExpr *Expr = getImm();
898 void addMemOperands(MCInst &Inst, unsigned N) const {
899 assert(N == 2 && "Invalid number of operands!");
901 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
902 ? getMemBase()->getGPR64Reg()
903 : getMemBase()->getGPR32Reg()));
905 const MCExpr *Expr = getMemOff();
909 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
910 assert(N == 2 && "Invalid number of operands!");
912 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
914 const MCExpr *Expr = getMemOff();
918 void addRegListOperands(MCInst &Inst, unsigned N) const {
919 assert(N == 1 && "Invalid number of operands!");
921 for (auto RegNo : getRegList())
922 Inst.addOperand(MCOperand::createReg(RegNo));
925 void addRegPairOperands(MCInst &Inst, unsigned N) const {
926 assert(N == 2 && "Invalid number of operands!");
927 unsigned RegNo = getRegPair();
928 Inst.addOperand(MCOperand::createReg(RegNo++));
929 Inst.addOperand(MCOperand::createReg(RegNo));
932 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
933 assert(N == 2 && "Invalid number of operands!");
934 for (auto RegNo : getRegList())
935 Inst.addOperand(MCOperand::createReg(RegNo));
938 bool isReg() const override {
939 // As a special case until we sort out the definition of div/divu, pretend
940 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
941 if (isGPRAsmReg() && RegIdx.Index == 0)
944 return Kind == k_PhysRegister;
946 bool isRegIdx() const { return Kind == k_RegisterIndex; }
947 bool isImm() const override { return Kind == k_Immediate; }
948 bool isConstantImm() const {
949 return isImm() && dyn_cast<MCConstantExpr>(getImm());
951 template <unsigned Bits> bool isUImm() const {
952 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
954 bool isToken() const override {
955 // Note: It's not possible to pretend that other operand kinds are tokens.
956 // The matcher emitter checks tokens first.
957 return Kind == k_Token;
959 bool isMem() const override { return Kind == k_Memory; }
960 bool isConstantMemOff() const {
961 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
963 template <unsigned Bits> bool isMemWithSimmOffset() const {
964 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
965 && getMemBase()->isGPRAsmReg();
967 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
968 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
969 getMemBase()->isGPRAsmReg();
971 bool isMemWithGRPMM16Base() const {
972 return isMem() && getMemBase()->isMM16AsmReg();
974 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
975 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
976 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
978 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
979 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
980 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
981 && (getMemBase()->getGPR32Reg() == Mips::SP);
983 bool isRegList16() const {
987 int Size = RegList.List->size();
988 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
989 RegList.List->back() != Mips::RA)
992 int PrevReg = *RegList.List->begin();
993 for (int i = 1; i < Size - 1; i++) {
994 int Reg = (*(RegList.List))[i];
995 if ( Reg != PrevReg + 1)
1002 bool isInvNum() const { return Kind == k_Immediate; }
1003 bool isLSAImm() const {
1004 if (!isConstantImm())
1006 int64_t Val = getConstantImm();
1007 return 1 <= Val && Val <= 4;
1009 bool isRegList() const { return Kind == k_RegList; }
1010 bool isMovePRegPair() const {
1011 if (Kind != k_RegList || RegList.List->size() != 2)
1014 unsigned R0 = RegList.List->front();
1015 unsigned R1 = RegList.List->back();
1017 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1018 (R0 == Mips::A1 && R1 == Mips::A3) ||
1019 (R0 == Mips::A2 && R1 == Mips::A3) ||
1020 (R0 == Mips::A0 && R1 == Mips::S5) ||
1021 (R0 == Mips::A0 && R1 == Mips::S6) ||
1022 (R0 == Mips::A0 && R1 == Mips::A1) ||
1023 (R0 == Mips::A0 && R1 == Mips::A2) ||
1024 (R0 == Mips::A0 && R1 == Mips::A3))
1030 StringRef getToken() const {
1031 assert(Kind == k_Token && "Invalid access!");
1032 return StringRef(Tok.Data, Tok.Length);
1034 bool isRegPair() const { return Kind == k_RegPair; }
1036 unsigned getReg() const override {
1037 // As a special case until we sort out the definition of div/divu, pretend
1038 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1039 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1040 RegIdx.Kind & RegKind_GPR)
1041 return getGPR32Reg(); // FIXME: GPR64 too
1043 assert(Kind == k_PhysRegister && "Invalid access!");
1047 const MCExpr *getImm() const {
1048 assert((Kind == k_Immediate) && "Invalid access!");
1052 int64_t getConstantImm() const {
1053 const MCExpr *Val = getImm();
1054 return static_cast<const MCConstantExpr *>(Val)->getValue();
1057 MipsOperand *getMemBase() const {
1058 assert((Kind == k_Memory) && "Invalid access!");
1062 const MCExpr *getMemOff() const {
1063 assert((Kind == k_Memory) && "Invalid access!");
1067 int64_t getConstantMemOff() const {
1068 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1071 const SmallVectorImpl<unsigned> &getRegList() const {
1072 assert((Kind == k_RegList) && "Invalid access!");
1073 return *(RegList.List);
1076 unsigned getRegPair() const {
1077 assert((Kind == k_RegPair) && "Invalid access!");
1078 return RegIdx.Index;
1081 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1082 MipsAsmParser &Parser) {
1083 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1084 Op->Tok.Data = Str.data();
1085 Op->Tok.Length = Str.size();
1091 /// Create a numeric register (e.g. $1). The exact register remains
1092 /// unresolved until an instruction successfully matches
1093 static std::unique_ptr<MipsOperand>
1094 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1095 SMLoc E, MipsAsmParser &Parser) {
1096 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1097 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1100 /// Create a register that is definitely a GPR.
1101 /// This is typically only used for named registers such as $gp.
1102 static std::unique_ptr<MipsOperand>
1103 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1104 MipsAsmParser &Parser) {
1105 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1108 /// Create a register that is definitely a FGR.
1109 /// This is typically only used for named registers such as $f0.
1110 static std::unique_ptr<MipsOperand>
1111 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1112 MipsAsmParser &Parser) {
1113 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1116 /// Create a register that is definitely a HWReg.
1117 /// This is typically only used for named registers such as $hwr_cpunum.
1118 static std::unique_ptr<MipsOperand>
1119 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1120 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1121 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1124 /// Create a register that is definitely an FCC.
1125 /// This is typically only used for named registers such as $fcc0.
1126 static std::unique_ptr<MipsOperand>
1127 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1128 MipsAsmParser &Parser) {
1129 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1132 /// Create a register that is definitely an ACC.
1133 /// This is typically only used for named registers such as $ac0.
1134 static std::unique_ptr<MipsOperand>
1135 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1136 MipsAsmParser &Parser) {
1137 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1140 /// Create a register that is definitely an MSA128.
1141 /// This is typically only used for named registers such as $w0.
1142 static std::unique_ptr<MipsOperand>
1143 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1144 SMLoc E, MipsAsmParser &Parser) {
1145 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1148 /// Create a register that is definitely an MSACtrl.
1149 /// This is typically only used for named registers such as $msaaccess.
1150 static std::unique_ptr<MipsOperand>
1151 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1152 SMLoc E, MipsAsmParser &Parser) {
1153 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1156 static std::unique_ptr<MipsOperand>
1157 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1158 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1165 static std::unique_ptr<MipsOperand>
1166 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1167 SMLoc E, MipsAsmParser &Parser) {
1168 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1169 Op->Mem.Base = Base.release();
1176 static std::unique_ptr<MipsOperand>
1177 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1178 MipsAsmParser &Parser) {
1179 assert (Regs.size() > 0 && "Empty list not allowed");
1181 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1182 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1183 Op->StartLoc = StartLoc;
1184 Op->EndLoc = EndLoc;
1188 static std::unique_ptr<MipsOperand>
1189 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1190 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1191 Op->RegIdx.Index = RegNo;
1197 bool isGPRAsmReg() const {
1198 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1200 bool isMM16AsmReg() const {
1201 if (!(isRegIdx() && RegIdx.Kind))
1203 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1204 || RegIdx.Index == 16 || RegIdx.Index == 17);
1206 bool isMM16AsmRegZero() const {
1207 if (!(isRegIdx() && RegIdx.Kind))
1209 return (RegIdx.Index == 0 ||
1210 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1211 RegIdx.Index == 17);
1213 bool isMM16AsmRegMoveP() const {
1214 if (!(isRegIdx() && RegIdx.Kind))
1216 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1217 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1219 bool isFGRAsmReg() const {
1220 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1221 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1223 bool isHWRegsAsmReg() const {
1224 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1226 bool isCCRAsmReg() const {
1227 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1229 bool isFCCAsmReg() const {
1230 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1232 if (!AsmParser.hasEightFccRegisters())
1233 return RegIdx.Index == 0;
1234 return RegIdx.Index <= 7;
1236 bool isACCAsmReg() const {
1237 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1239 bool isCOP0AsmReg() const {
1240 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1242 bool isCOP2AsmReg() const {
1243 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1245 bool isCOP3AsmReg() const {
1246 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1248 bool isMSA128AsmReg() const {
1249 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1251 bool isMSACtrlAsmReg() const {
1252 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1255 /// getStartLoc - Get the location of the first token of this operand.
1256 SMLoc getStartLoc() const override { return StartLoc; }
1257 /// getEndLoc - Get the location of the last token of this operand.
1258 SMLoc getEndLoc() const override { return EndLoc; }
1260 virtual ~MipsOperand() {
1268 delete RegList.List;
1269 case k_PhysRegister:
1270 case k_RegisterIndex:
1277 void print(raw_ostream &OS) const override {
1286 Mem.Base->print(OS);
1291 case k_PhysRegister:
1292 OS << "PhysReg<" << PhysReg.Num << ">";
1294 case k_RegisterIndex:
1295 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1302 for (auto Reg : (*RegList.List))
1307 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1311 }; // class MipsOperand
1315 extern const MCInstrDesc MipsInsts[];
1317 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1318 return MipsInsts[Opcode];
1321 static bool hasShortDelaySlot(unsigned Opcode) {
1324 case Mips::JALRS_MM:
1325 case Mips::JALRS16_MM:
1326 case Mips::BGEZALS_MM:
1327 case Mips::BLTZALS_MM:
1334 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1335 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1336 return &SRExpr->getSymbol();
1339 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1340 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1341 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1352 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1353 return getSingleMCSymbol(UExpr->getSubExpr());
1358 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1359 if (isa<MCSymbolRefExpr>(Expr))
1362 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1363 return countMCSymbolRefExpr(BExpr->getLHS()) +
1364 countMCSymbolRefExpr(BExpr->getRHS());
1366 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1367 return countMCSymbolRefExpr(UExpr->getSubExpr());
1372 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1373 SmallVectorImpl<MCInst> &Instructions) {
1374 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1375 bool ExpandedJalSym = false;
1379 if (MCID.isBranch() || MCID.isCall()) {
1380 const unsigned Opcode = Inst.getOpcode();
1390 assert(hasCnMips() && "instruction only valid for octeon cpus");
1397 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1398 Offset = Inst.getOperand(2);
1399 if (!Offset.isImm())
1400 break; // We'll deal with this situation later on when applying fixups.
1401 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1402 return Error(IDLoc, "branch target out of range");
1403 if (OffsetToAlignment(Offset.getImm(),
1404 1LL << (inMicroMipsMode() ? 1 : 2)))
1405 return Error(IDLoc, "branch to misaligned address");
1419 case Mips::BGEZAL_MM:
1420 case Mips::BLTZAL_MM:
1423 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1424 Offset = Inst.getOperand(1);
1425 if (!Offset.isImm())
1426 break; // We'll deal with this situation later on when applying fixups.
1427 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1428 return Error(IDLoc, "branch target out of range");
1429 if (OffsetToAlignment(Offset.getImm(),
1430 1LL << (inMicroMipsMode() ? 1 : 2)))
1431 return Error(IDLoc, "branch to misaligned address");
1433 case Mips::BEQZ16_MM:
1434 case Mips::BEQZC16_MMR6:
1435 case Mips::BNEZ16_MM:
1436 case Mips::BNEZC16_MMR6:
1437 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1438 Offset = Inst.getOperand(1);
1439 if (!Offset.isImm())
1440 break; // We'll deal with this situation later on when applying fixups.
1441 if (!isIntN(8, Offset.getImm()))
1442 return Error(IDLoc, "branch target out of range");
1443 if (OffsetToAlignment(Offset.getImm(), 2LL))
1444 return Error(IDLoc, "branch to misaligned address");
1449 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1450 // We still accept it but it is a normal nop.
1451 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1452 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1453 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1458 const unsigned Opcode = Inst.getOpcode();
1470 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1471 // The offset is handled above
1472 Opnd = Inst.getOperand(1);
1474 return Error(IDLoc, "expected immediate operand kind");
1475 Imm = Opnd.getImm();
1476 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1477 Opcode == Mips::BBIT1 ? 63 : 31))
1478 return Error(IDLoc, "immediate operand value out of range");
1480 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1482 Inst.getOperand(1).setImm(Imm - 32);
1490 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1492 Opnd = Inst.getOperand(3);
1494 return Error(IDLoc, "expected immediate operand kind");
1495 Imm = Opnd.getImm();
1496 if (Imm < 0 || Imm > 31)
1497 return Error(IDLoc, "immediate operand value out of range");
1499 Opnd = Inst.getOperand(2);
1501 return Error(IDLoc, "expected immediate operand kind");
1502 Imm = Opnd.getImm();
1503 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1504 Opcode == Mips::EXTS ? 63 : 31))
1505 return Error(IDLoc, "immediate operand value out of range");
1507 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1508 Inst.getOperand(2).setImm(Imm - 32);
1514 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1515 Opnd = Inst.getOperand(2);
1517 return Error(IDLoc, "expected immediate operand kind");
1518 Imm = Opnd.getImm();
1519 if (!isInt<10>(Imm))
1520 return Error(IDLoc, "immediate operand value out of range");
1525 // This expansion is not in a function called by expandInstruction() because
1526 // the pseudo-instruction doesn't have a distinct opcode.
1527 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1529 warnIfNoMacro(IDLoc);
1531 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1533 // We can do this expansion if there's only 1 symbol in the argument
1535 if (countMCSymbolRefExpr(JalExpr) > 1)
1536 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1538 // FIXME: This is checking the expression can be handled by the later stages
1539 // of the assembler. We ought to leave it to those later stages but
1540 // we can't do that until we stop evaluateRelocExpr() rewriting the
1541 // expressions into non-equivalent forms.
1542 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1544 // FIXME: Add support for label+offset operands (currently causes an error).
1545 // FIXME: Add support for forward-declared local symbols.
1546 // FIXME: Add expansion for when the LargeGOT option is enabled.
1547 if (JalSym->isInSection() || JalSym->isTemporary()) {
1549 // If it's a local symbol and the O32 ABI is being used, we expand to:
1551 // R_(MICRO)MIPS_GOT16 label
1552 // addiu $25, $25, 0
1553 // R_(MICRO)MIPS_LO16 label
1555 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1556 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1559 LwInst.setOpcode(Mips::LW);
1560 LwInst.addOperand(MCOperand::createReg(Mips::T9));
1561 LwInst.addOperand(MCOperand::createReg(Mips::GP));
1562 LwInst.addOperand(MCOperand::createExpr(Got16RelocExpr));
1563 Instructions.push_back(LwInst);
1566 AddiuInst.setOpcode(Mips::ADDiu);
1567 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1568 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1569 AddiuInst.addOperand(MCOperand::createExpr(Lo16RelocExpr));
1570 Instructions.push_back(AddiuInst);
1571 } else if (isABI_N32() || isABI_N64()) {
1572 // If it's a local symbol and the N32/N64 ABIs are being used,
1574 // lw/ld $25, 0($gp)
1575 // R_(MICRO)MIPS_GOT_DISP label
1577 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1580 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1581 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1582 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1583 LoadInst.addOperand(MCOperand::createExpr(GotDispRelocExpr));
1584 Instructions.push_back(LoadInst);
1587 // If it's an external/weak symbol, we expand to:
1588 // lw/ld $25, 0($gp)
1589 // R_(MICRO)MIPS_CALL16 label
1591 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1594 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1595 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1596 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1597 LoadInst.addOperand(MCOperand::createExpr(Call16RelocExpr));
1598 Instructions.push_back(LoadInst);
1602 if (IsCpRestoreSet && inMicroMipsMode())
1603 JalrInst.setOpcode(Mips::JALRS_MM);
1605 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1606 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1607 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1609 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1610 // This relocation is supposed to be an optimization hint for the linker
1611 // and is not necessary for correctness.
1614 ExpandedJalSym = true;
1617 if (MCID.mayLoad() || MCID.mayStore()) {
1618 // Check the offset of memory operand, if it is a symbol
1619 // reference or immediate we may have to expand instructions.
1620 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1621 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1622 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1623 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1624 MCOperand &Op = Inst.getOperand(i);
1626 int MemOffset = Op.getImm();
1627 if (MemOffset < -32768 || MemOffset > 32767) {
1628 // Offset can't exceed 16bit value.
1629 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1632 } else if (Op.isExpr()) {
1633 const MCExpr *Expr = Op.getExpr();
1634 if (Expr->getKind() == MCExpr::SymbolRef) {
1635 const MCSymbolRefExpr *SR =
1636 static_cast<const MCSymbolRefExpr *>(Expr);
1637 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1639 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1642 } else if (!isEvaluated(Expr)) {
1643 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1651 if (inMicroMipsMode()) {
1652 if (MCID.mayLoad()) {
1653 // Try to create 16-bit GP relative load instruction.
1654 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1655 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1656 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1657 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1658 MCOperand &Op = Inst.getOperand(i);
1660 int MemOffset = Op.getImm();
1661 MCOperand &DstReg = Inst.getOperand(0);
1662 MCOperand &BaseReg = Inst.getOperand(1);
1663 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1664 getContext().getRegisterInfo()->getRegClass(
1665 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1666 (BaseReg.getReg() == Mips::GP ||
1667 BaseReg.getReg() == Mips::GP_64)) {
1669 TmpInst.setLoc(IDLoc);
1670 TmpInst.setOpcode(Mips::LWGP_MM);
1671 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1672 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1673 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1674 Instructions.push_back(TmpInst);
1682 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1687 switch (Inst.getOpcode()) {
1690 case Mips::ADDIUS5_MM:
1691 Opnd = Inst.getOperand(2);
1693 return Error(IDLoc, "expected immediate operand kind");
1694 Imm = Opnd.getImm();
1695 if (Imm < -8 || Imm > 7)
1696 return Error(IDLoc, "immediate operand value out of range");
1698 case Mips::ADDIUSP_MM:
1699 Opnd = Inst.getOperand(0);
1701 return Error(IDLoc, "expected immediate operand kind");
1702 Imm = Opnd.getImm();
1703 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1705 return Error(IDLoc, "immediate operand value out of range");
1707 case Mips::SLL16_MM:
1708 case Mips::SRL16_MM:
1709 Opnd = Inst.getOperand(2);
1711 return Error(IDLoc, "expected immediate operand kind");
1712 Imm = Opnd.getImm();
1713 if (Imm < 1 || Imm > 8)
1714 return Error(IDLoc, "immediate operand value out of range");
1717 Opnd = Inst.getOperand(1);
1719 return Error(IDLoc, "expected immediate operand kind");
1720 Imm = Opnd.getImm();
1721 if (Imm < -1 || Imm > 126)
1722 return Error(IDLoc, "immediate operand value out of range");
1724 case Mips::ADDIUR2_MM:
1725 Opnd = Inst.getOperand(2);
1727 return Error(IDLoc, "expected immediate operand kind");
1728 Imm = Opnd.getImm();
1729 if (!(Imm == 1 || Imm == -1 ||
1730 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1731 return Error(IDLoc, "immediate operand value out of range");
1733 case Mips::ADDIUR1SP_MM:
1734 Opnd = Inst.getOperand(1);
1736 return Error(IDLoc, "expected immediate operand kind");
1737 Imm = Opnd.getImm();
1738 if (OffsetToAlignment(Imm, 4LL))
1739 return Error(IDLoc, "misaligned immediate operand value");
1740 if (Imm < 0 || Imm > 255)
1741 return Error(IDLoc, "immediate operand value out of range");
1743 case Mips::ANDI16_MM:
1744 Opnd = Inst.getOperand(2);
1746 return Error(IDLoc, "expected immediate operand kind");
1747 Imm = Opnd.getImm();
1748 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1749 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1750 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1751 return Error(IDLoc, "immediate operand value out of range");
1753 case Mips::LBU16_MM:
1754 Opnd = Inst.getOperand(2);
1756 return Error(IDLoc, "expected immediate operand kind");
1757 Imm = Opnd.getImm();
1758 if (Imm < -1 || Imm > 14)
1759 return Error(IDLoc, "immediate operand value out of range");
1768 Opnd = Inst.getOperand(2);
1770 return Error(IDLoc, "expected immediate operand kind");
1771 Imm = Opnd.getImm();
1772 if (Imm < 0 || Imm > 15)
1773 return Error(IDLoc, "immediate operand value out of range");
1775 case Mips::LHU16_MM:
1777 Opnd = Inst.getOperand(2);
1779 return Error(IDLoc, "expected immediate operand kind");
1780 Imm = Opnd.getImm();
1781 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1782 return Error(IDLoc, "immediate operand value out of range");
1786 Opnd = Inst.getOperand(2);
1788 return Error(IDLoc, "expected immediate operand kind");
1789 Imm = Opnd.getImm();
1790 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1791 return Error(IDLoc, "immediate operand value out of range");
1793 case Mips::PREFX_MM:
1796 Opnd = Inst.getOperand(2);
1798 return Error(IDLoc, "expected immediate operand kind");
1799 Imm = Opnd.getImm();
1800 if (!isUInt<5>(Imm))
1801 return Error(IDLoc, "immediate operand value out of range");
1803 case Mips::ADDIUPC_MM:
1804 MCOperand Opnd = Inst.getOperand(1);
1806 return Error(IDLoc, "expected immediate operand kind");
1807 int Imm = Opnd.getImm();
1808 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1809 return Error(IDLoc, "immediate operand value out of range");
1814 if (needsExpansion(Inst)) {
1815 if (expandInstruction(Inst, IDLoc, Instructions))
1818 Instructions.push_back(Inst);
1820 // If this instruction has a delay slot and .set reorder is active,
1821 // emit a NOP after it.
1822 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1823 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1825 if ((Inst.getOpcode() == Mips::JalOneReg ||
1826 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1827 isPicAndNotNxxAbi()) {
1828 if (IsCpRestoreSet) {
1829 // We need a NOP between the JALR and the LW:
1830 // If .set reorder has been used, we've already emitted a NOP.
1831 // If .set noreorder has been used, we need to emit a NOP at this point.
1832 if (!AssemblerOptions.back()->isReorder())
1833 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1835 // Load the $gp from the stack.
1836 SmallVector<MCInst, 3> LoadInsts;
1837 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1840 for (const MCInst &Inst : LoadInsts)
1841 Instructions.push_back(Inst);
1844 Warning(IDLoc, "no .cprestore used in PIC mode");
1850 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1852 switch (Inst.getOpcode()) {
1853 case Mips::LoadImm32:
1854 case Mips::LoadImm64:
1855 case Mips::LoadAddrImm32:
1856 case Mips::LoadAddrImm64:
1857 case Mips::LoadAddrReg32:
1858 case Mips::LoadAddrReg64:
1859 case Mips::B_MM_Pseudo:
1860 case Mips::B_MMR6_Pseudo:
1863 case Mips::JalOneReg:
1864 case Mips::JalTwoReg:
1883 case Mips::SDivMacro:
1884 case Mips::UDivMacro:
1885 case Mips::DSDivMacro:
1886 case Mips::DUDivMacro:
1895 if ((Inst.getNumOperands() == 3) &&
1896 Inst.getOperand(0).isReg() &&
1897 Inst.getOperand(1).isReg() &&
1898 Inst.getOperand(2).isImm()) {
1899 int64_t ImmValue = Inst.getOperand(2).getImm();
1900 return !isInt<16>(ImmValue);
1906 if ((Inst.getNumOperands() == 3) &&
1907 Inst.getOperand(0).isReg() &&
1908 Inst.getOperand(1).isReg() &&
1909 Inst.getOperand(2).isImm()) {
1910 int64_t ImmValue = Inst.getOperand(2).getImm();
1911 return !isUInt<16>(ImmValue);
1919 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1920 SmallVectorImpl<MCInst> &Instructions) {
1921 switch (Inst.getOpcode()) {
1922 default: llvm_unreachable("unimplemented expansion");
1923 case Mips::LoadImm32:
1924 return expandLoadImm(Inst, true, IDLoc, Instructions);
1925 case Mips::LoadImm64:
1926 return expandLoadImm(Inst, false, IDLoc, Instructions);
1927 case Mips::LoadAddrImm32:
1928 case Mips::LoadAddrImm64:
1929 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1930 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1931 "expected immediate operand kind");
1933 return expandLoadAddress(
1934 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1935 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1936 case Mips::LoadAddrReg32:
1937 case Mips::LoadAddrReg64:
1938 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1939 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1940 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1941 "expected immediate operand kind");
1943 return expandLoadAddress(
1944 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1945 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1946 case Mips::B_MM_Pseudo:
1947 case Mips::B_MMR6_Pseudo:
1948 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1951 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1952 case Mips::JalOneReg:
1953 case Mips::JalTwoReg:
1954 return expandJalWithRegs(Inst, IDLoc, Instructions);
1957 return expandBranchImm(Inst, IDLoc, Instructions);
1974 return expandCondBranches(Inst, IDLoc, Instructions);
1975 case Mips::SDivMacro:
1976 return expandDiv(Inst, IDLoc, Instructions, false, true);
1977 case Mips::DSDivMacro:
1978 return expandDiv(Inst, IDLoc, Instructions, true, true);
1979 case Mips::UDivMacro:
1980 return expandDiv(Inst, IDLoc, Instructions, false, false);
1981 case Mips::DUDivMacro:
1982 return expandDiv(Inst, IDLoc, Instructions, true, false);
1984 return expandUlhu(Inst, IDLoc, Instructions);
1986 return expandUlw(Inst, IDLoc, Instructions);
1995 return expandAliasImmediate(Inst, IDLoc, Instructions);
2000 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
2001 SmallVectorImpl<MCInst> &Instructions) {
2003 tmpInst.setOpcode(Opcode);
2004 tmpInst.addOperand(MCOperand::createReg(Reg0));
2005 tmpInst.addOperand(Op1);
2006 tmpInst.setLoc(IDLoc);
2007 Instructions.push_back(tmpInst);
2010 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
2011 SmallVectorImpl<MCInst> &Instructions) {
2012 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
2015 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
2016 SmallVectorImpl<MCInst> &Instructions) {
2017 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
2020 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
2021 SmallVectorImpl<MCInst> &Instructions) {
2023 tmpInst.setOpcode(Opcode);
2024 tmpInst.addOperand(MCOperand::createImm(Imm1));
2025 tmpInst.addOperand(MCOperand::createImm(Imm2));
2026 tmpInst.setLoc(IDLoc);
2027 Instructions.push_back(tmpInst);
2030 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
2031 SmallVectorImpl<MCInst> &Instructions) {
2033 tmpInst.setOpcode(Opcode);
2034 tmpInst.addOperand(MCOperand::createReg(Reg0));
2035 tmpInst.setLoc(IDLoc);
2036 Instructions.push_back(tmpInst);
2039 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
2040 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2042 tmpInst.setOpcode(Opcode);
2043 tmpInst.addOperand(MCOperand::createReg(Reg0));
2044 tmpInst.addOperand(MCOperand::createReg(Reg1));
2045 tmpInst.addOperand(Op2);
2046 tmpInst.setLoc(IDLoc);
2047 Instructions.push_back(tmpInst);
2050 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
2051 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2052 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
2056 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
2057 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2058 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
2062 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
2063 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2064 if (ShiftAmount >= 32) {
2065 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
2070 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
2072 } // end anonymous namespace.
2074 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2075 SmallVectorImpl<MCInst> &Instructions) {
2076 // Create a JALR instruction which is going to replace the pseudo-JAL.
2078 JalrInst.setLoc(IDLoc);
2079 const MCOperand FirstRegOp = Inst.getOperand(0);
2080 const unsigned Opcode = Inst.getOpcode();
2082 if (Opcode == Mips::JalOneReg) {
2083 // jal $rs => jalr $rs
2084 if (IsCpRestoreSet && inMicroMipsMode()) {
2085 JalrInst.setOpcode(Mips::JALRS16_MM);
2086 JalrInst.addOperand(FirstRegOp);
2087 } else if (inMicroMipsMode()) {
2088 JalrInst.setOpcode(Mips::JALR16_MM);
2089 JalrInst.addOperand(FirstRegOp);
2091 JalrInst.setOpcode(Mips::JALR);
2092 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2093 JalrInst.addOperand(FirstRegOp);
2095 } else if (Opcode == Mips::JalTwoReg) {
2096 // jal $rd, $rs => jalr $rd, $rs
2097 if (IsCpRestoreSet && inMicroMipsMode())
2098 JalrInst.setOpcode(Mips::JALRS_MM);
2100 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2101 JalrInst.addOperand(FirstRegOp);
2102 const MCOperand SecondRegOp = Inst.getOperand(1);
2103 JalrInst.addOperand(SecondRegOp);
2105 Instructions.push_back(JalrInst);
2107 // If .set reorder is active, emit a NOP after it.
2108 if (AssemblerOptions.back()->isReorder())
2109 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2114 /// Can the value be represented by a unsigned N-bit value and a shift left?
2115 template<unsigned N>
2116 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2117 unsigned BitNum = findFirstSet(x);
2119 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2122 /// Load (or add) an immediate into a register.
2124 /// @param ImmValue The immediate to load.
2125 /// @param DstReg The register that will hold the immediate.
2126 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2127 /// for a simple initialization.
2128 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2129 /// @param IsAddress True if the immediate represents an address. False if it
2131 /// @param IDLoc Location of the immediate in the source file.
2132 /// @param Instructions The instructions emitted by this expansion.
2133 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2134 unsigned SrcReg, bool Is32BitImm,
2135 bool IsAddress, SMLoc IDLoc,
2136 SmallVectorImpl<MCInst> &Instructions) {
2137 if (!Is32BitImm && !isGP64bit()) {
2138 Error(IDLoc, "instruction requires a 64-bit architecture");
2143 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2144 // Sign extend up to 64-bit so that the predicates match the hardware
2145 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2147 ImmValue = SignExtend64<32>(ImmValue);
2149 Error(IDLoc, "instruction requires a 32-bit immediate");
2154 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2155 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2157 bool UseSrcReg = false;
2158 if (SrcReg != Mips::NoRegister)
2161 unsigned TmpReg = DstReg;
2162 if (UseSrcReg && (DstReg == SrcReg)) {
2163 // At this point we need AT to perform the expansions and we exit if it is
2165 unsigned ATReg = getATReg(IDLoc);
2171 if (isInt<16>(ImmValue)) {
2175 // This doesn't quite follow the usual ABI expectations for N32 but matches
2176 // traditional assembler behaviour. N32 would normally use addiu for both
2177 // integers and addresses.
2178 if (IsAddress && !Is32BitImm) {
2179 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2183 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2187 if (isUInt<16>(ImmValue)) {
2188 unsigned TmpReg = DstReg;
2189 if (SrcReg == DstReg) {
2190 TmpReg = getATReg(IDLoc);
2195 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2197 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2201 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2202 warnIfNoMacro(IDLoc);
2204 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2205 uint16_t Bits15To0 = ImmValue & 0xffff;
2207 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2208 // Traditional behaviour seems to special case this particular value. It's
2209 // not clear why other masks are handled differently.
2210 if (ImmValue == 0xffffffff) {
2211 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2212 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2214 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2218 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2220 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2221 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2223 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2225 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2229 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2231 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2233 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2237 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2239 Error(IDLoc, "instruction requires a 32-bit immediate");
2243 // Traditionally, these immediates are shifted as little as possible and as
2244 // such we align the most significant bit to bit 15 of our temporary.
2245 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2246 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2247 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2248 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2249 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2250 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2253 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2258 warnIfNoMacro(IDLoc);
2260 // The remaining case is packed with a sequence of dsll and ori with zeros
2261 // being omitted and any neighbouring dsll's being coalesced.
2262 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2264 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2265 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2266 IDLoc, Instructions))
2269 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2270 // skip it and defer the shift to the next chunk.
2271 unsigned ShiftCarriedForwards = 16;
2272 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2273 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2275 if (ImmChunk != 0) {
2276 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2278 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2279 ShiftCarriedForwards = 0;
2282 ShiftCarriedForwards += 16;
2284 ShiftCarriedForwards -= 16;
2286 // Finish any remaining shifts left by trailing zeros.
2287 if (ShiftCarriedForwards)
2288 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2292 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2297 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2298 SmallVectorImpl<MCInst> &Instructions) {
2299 const MCOperand &ImmOp = Inst.getOperand(1);
2300 assert(ImmOp.isImm() && "expected immediate operand kind");
2301 const MCOperand &DstRegOp = Inst.getOperand(0);
2302 assert(DstRegOp.isReg() && "expected register operand kind");
2304 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2305 Is32BitImm, false, IDLoc, Instructions))
2311 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2312 const MCOperand &Offset,
2313 bool Is32BitAddress, SMLoc IDLoc,
2314 SmallVectorImpl<MCInst> &Instructions) {
2315 // la can't produce a usable address when addresses are 64-bit.
2316 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2317 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2318 // We currently can't do this because we depend on the equality
2319 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2320 Error(IDLoc, "la used to load 64-bit address");
2321 // Continue as if we had 'dla' instead.
2322 Is32BitAddress = false;
2325 // dla requires 64-bit addresses.
2326 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2327 Error(IDLoc, "instruction requires a 64-bit architecture");
2331 if (!Offset.isImm())
2332 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2333 Is32BitAddress, IDLoc, Instructions);
2335 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2336 IDLoc, Instructions);
2339 bool MipsAsmParser::loadAndAddSymbolAddress(
2340 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2341 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2342 warnIfNoMacro(IDLoc);
2344 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2345 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2346 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2347 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2348 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2350 bool UseSrcReg = SrcReg != Mips::NoRegister;
2352 // This is the 64-bit symbol address expansion.
2353 if (ABI.ArePtrs64bit() && isGP64bit()) {
2354 // We always need AT for the 64-bit expansion.
2355 // If it is not available we exit.
2356 unsigned ATReg = getATReg(IDLoc);
2360 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2361 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2362 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2363 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2365 if (UseSrcReg && (DstReg == SrcReg)) {
2366 // If $rs is the same as $rd:
2367 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2368 // daddiu $at, $at, %higher(sym)
2369 // dsll $at, $at, 16
2370 // daddiu $at, $at, %hi(sym)
2371 // dsll $at, $at, 16
2372 // daddiu $at, $at, %lo(sym)
2373 // daddu $rd, $at, $rd
2374 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2376 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2377 IDLoc, Instructions);
2378 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2379 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2381 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2382 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2384 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2389 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2390 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2391 // lui $at, %hi(sym)
2392 // daddiu $rd, $rd, %higher(sym)
2393 // daddiu $at, $at, %lo(sym)
2394 // dsll32 $rd, $rd, 0
2395 // daddu $rd, $rd, $at
2396 // (daddu $rd, $rd, $rs)
2397 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2399 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2401 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2402 IDLoc, Instructions);
2403 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2405 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2406 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2408 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2413 // And now, the 32-bit symbol address expansion:
2414 // If $rs is the same as $rd:
2415 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2416 // ori $at, $at, %lo(sym)
2417 // addu $rd, $at, $rd
2418 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2419 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2420 // ori $rd, $rd, %lo(sym)
2421 // (addu $rd, $rd, $rs)
2422 unsigned TmpReg = DstReg;
2423 if (UseSrcReg && (DstReg == SrcReg)) {
2424 // If $rs is the same as $rd, we need to use AT.
2425 // If it is not available we exit.
2426 unsigned ATReg = getATReg(IDLoc);
2432 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2433 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2437 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2439 assert(DstReg == TmpReg);
2444 bool MipsAsmParser::expandUncondBranchMMPseudo(
2445 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2446 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2447 "unexpected number of operands");
2449 MCOperand Offset = Inst.getOperand(0);
2450 if (Offset.isExpr()) {
2452 Inst.setOpcode(Mips::BEQ_MM);
2453 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2454 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2455 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2457 assert(Offset.isImm() && "expected immediate operand kind");
2458 if (isIntN(11, Offset.getImm())) {
2459 // If offset fits into 11 bits then this instruction becomes microMIPS
2460 // 16-bit unconditional branch instruction.
2461 if (inMicroMipsMode())
2462 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2464 if (!isIntN(17, Offset.getImm()))
2465 Error(IDLoc, "branch target out of range");
2466 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2467 Error(IDLoc, "branch to misaligned address");
2469 Inst.setOpcode(Mips::BEQ_MM);
2470 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2471 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2472 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2475 Instructions.push_back(Inst);
2477 // If .set reorder is active and branch instruction has a delay slot,
2478 // emit a NOP after it.
2479 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2480 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2481 createNop(true, IDLoc, Instructions);
2486 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2487 SmallVectorImpl<MCInst> &Instructions) {
2488 const MCOperand &DstRegOp = Inst.getOperand(0);
2489 assert(DstRegOp.isReg() && "expected register operand kind");
2491 const MCOperand &ImmOp = Inst.getOperand(1);
2492 assert(ImmOp.isImm() && "expected immediate operand kind");
2494 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2495 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2497 unsigned OpCode = 0;
2498 switch(Inst.getOpcode()) {
2506 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2510 int64_t ImmValue = ImmOp.getImm();
2511 if (ImmValue == 0) {
2513 BranchInst.setOpcode(OpCode);
2514 BranchInst.addOperand(DstRegOp);
2515 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2516 BranchInst.addOperand(MemOffsetOp);
2517 Instructions.push_back(BranchInst);
2519 warnIfNoMacro(IDLoc);
2521 unsigned ATReg = getATReg(IDLoc);
2525 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2526 IDLoc, Instructions))
2530 BranchInst.setOpcode(OpCode);
2531 BranchInst.addOperand(DstRegOp);
2532 BranchInst.addOperand(MCOperand::createReg(ATReg));
2533 BranchInst.addOperand(MemOffsetOp);
2534 Instructions.push_back(BranchInst);
2539 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2540 SmallVectorImpl<MCInst> &Instructions,
2541 bool isLoad, bool isImmOpnd) {
2543 unsigned ImmOffset, HiOffset, LoOffset;
2544 const MCExpr *ExprOffset;
2546 // 1st operand is either the source or destination register.
2547 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2548 unsigned RegOpNum = Inst.getOperand(0).getReg();
2549 // 2nd operand is the base register.
2550 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2551 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2552 // 3rd operand is either an immediate or expression.
2554 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2555 ImmOffset = Inst.getOperand(2).getImm();
2556 LoOffset = ImmOffset & 0x0000ffff;
2557 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2558 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2559 if (LoOffset & 0x8000)
2562 ExprOffset = Inst.getOperand(2).getExpr();
2563 // All instructions will have the same location.
2564 TempInst.setLoc(IDLoc);
2565 // These are some of the types of expansions we perform here:
2566 // 1) lw $8, sym => lui $8, %hi(sym)
2567 // lw $8, %lo(sym)($8)
2568 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2570 // lw $8, %lo(offset)($9)
2571 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2573 // lw $8, %lo(offset)($at)
2574 // 4) sw $8, sym => lui $at, %hi(sym)
2575 // sw $8, %lo(sym)($at)
2576 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2578 // sw $8, %lo(offset)($at)
2579 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2580 // ldc1 $f0, %lo(sym)($at)
2582 // For load instructions we can use the destination register as a temporary
2583 // if base and dst are different (examples 1 and 2) and if the base register
2584 // is general purpose otherwise we must use $at (example 6) and error if it's
2585 // not available. For stores we must use $at (examples 4 and 5) because we
2586 // must not clobber the source register setting up the offset.
2587 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2588 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2589 unsigned RegClassIDOp0 =
2590 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2591 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2592 (RegClassIDOp0 == Mips::GPR64RegClassID);
2593 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2594 TmpRegNum = RegOpNum;
2596 // At this point we need AT to perform the expansions and we exit if it is
2598 TmpRegNum = getATReg(IDLoc);
2603 TempInst.setOpcode(Mips::LUi);
2604 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2606 TempInst.addOperand(MCOperand::createImm(HiOffset));
2608 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2609 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2611 // Add the instruction to the list.
2612 Instructions.push_back(TempInst);
2613 // Prepare TempInst for next instruction.
2615 // Add temp register to base.
2616 if (BaseRegNum != Mips::ZERO) {
2617 TempInst.setOpcode(Mips::ADDu);
2618 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2619 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2620 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2621 Instructions.push_back(TempInst);
2624 // And finally, create original instruction with low part
2625 // of offset and new base.
2626 TempInst.setOpcode(Inst.getOpcode());
2627 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2628 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2630 TempInst.addOperand(MCOperand::createImm(LoOffset));
2632 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2633 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2635 Instructions.push_back(TempInst);
2640 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2641 SmallVectorImpl<MCInst> &Instructions) {
2642 unsigned OpNum = Inst.getNumOperands();
2643 unsigned Opcode = Inst.getOpcode();
2644 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2646 assert (Inst.getOperand(OpNum - 1).isImm() &&
2647 Inst.getOperand(OpNum - 2).isReg() &&
2648 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2650 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2651 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2652 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2653 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2654 // It can be implemented as SWM16 or LWM16 instruction.
2655 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2657 Inst.setOpcode(NewOpcode);
2658 Instructions.push_back(Inst);
2662 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2663 SmallVectorImpl<MCInst> &Instructions) {
2664 unsigned PseudoOpcode = Inst.getOpcode();
2665 unsigned SrcReg = Inst.getOperand(0).getReg();
2666 unsigned TrgReg = Inst.getOperand(1).getReg();
2667 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2669 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2670 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2672 switch (PseudoOpcode) {
2677 AcceptsEquality = false;
2678 ReverseOrderSLT = false;
2679 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2680 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2681 ZeroSrcOpcode = Mips::BGTZ;
2682 ZeroTrgOpcode = Mips::BLTZ;
2688 AcceptsEquality = true;
2689 ReverseOrderSLT = true;
2690 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2691 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2692 ZeroSrcOpcode = Mips::BGEZ;
2693 ZeroTrgOpcode = Mips::BLEZ;
2699 AcceptsEquality = true;
2700 ReverseOrderSLT = false;
2701 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2702 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2703 ZeroSrcOpcode = Mips::BLEZ;
2704 ZeroTrgOpcode = Mips::BGEZ;
2710 AcceptsEquality = false;
2711 ReverseOrderSLT = true;
2712 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2713 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2714 ZeroSrcOpcode = Mips::BLTZ;
2715 ZeroTrgOpcode = Mips::BGTZ;
2718 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2722 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2723 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2724 if (IsSrcRegZero && IsTrgRegZero) {
2725 // FIXME: All of these Opcode-specific if's are needed for compatibility
2726 // with GAS' behaviour. However, they may not generate the most efficient
2727 // code in some circumstances.
2728 if (PseudoOpcode == Mips::BLT) {
2729 BranchInst.setOpcode(Mips::BLTZ);
2730 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2731 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2732 Instructions.push_back(BranchInst);
2735 if (PseudoOpcode == Mips::BLE) {
2736 BranchInst.setOpcode(Mips::BLEZ);
2737 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2738 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2739 Instructions.push_back(BranchInst);
2740 Warning(IDLoc, "branch is always taken");
2743 if (PseudoOpcode == Mips::BGE) {
2744 BranchInst.setOpcode(Mips::BGEZ);
2745 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2746 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2747 Instructions.push_back(BranchInst);
2748 Warning(IDLoc, "branch is always taken");
2751 if (PseudoOpcode == Mips::BGT) {
2752 BranchInst.setOpcode(Mips::BGTZ);
2753 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2754 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2755 Instructions.push_back(BranchInst);
2758 if (PseudoOpcode == Mips::BGTU) {
2759 BranchInst.setOpcode(Mips::BNE);
2760 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2761 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2762 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2763 Instructions.push_back(BranchInst);
2766 if (AcceptsEquality) {
2767 // If both registers are $0 and the pseudo-branch accepts equality, it
2768 // will always be taken, so we emit an unconditional branch.
2769 BranchInst.setOpcode(Mips::BEQ);
2770 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2771 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2772 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2773 Instructions.push_back(BranchInst);
2774 Warning(IDLoc, "branch is always taken");
2777 // If both registers are $0 and the pseudo-branch does not accept
2778 // equality, it will never be taken, so we don't have to emit anything.
2781 if (IsSrcRegZero || IsTrgRegZero) {
2782 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2783 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2784 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2785 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2786 // the pseudo-branch will never be taken, so we don't emit anything.
2787 // This only applies to unsigned pseudo-branches.
2790 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2791 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2792 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2793 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2794 // the pseudo-branch will always be taken, so we emit an unconditional
2796 // This only applies to unsigned pseudo-branches.
2797 BranchInst.setOpcode(Mips::BEQ);
2798 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2799 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2800 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2801 Instructions.push_back(BranchInst);
2802 Warning(IDLoc, "branch is always taken");
2806 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2807 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2808 // the pseudo-branch will be taken only when the non-zero register is
2809 // different from 0, so we emit a BNEZ.
2811 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2812 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2813 // the pseudo-branch will be taken only when the non-zero register is
2814 // equal to 0, so we emit a BEQZ.
2816 // Because only BLEU and BGEU branch on equality, we can use the
2817 // AcceptsEquality variable to decide when to emit the BEQZ.
2818 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2819 BranchInst.addOperand(
2820 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2821 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2822 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2823 Instructions.push_back(BranchInst);
2826 // If we have a signed pseudo-branch and one of the registers is $0,
2827 // we can use an appropriate compare-to-zero branch. We select which one
2828 // to use in the switch statement above.
2829 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2830 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2831 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2832 Instructions.push_back(BranchInst);
2836 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2837 // expansions. If it is not available, we return.
2838 unsigned ATRegNum = getATReg(IDLoc);
2842 warnIfNoMacro(IDLoc);
2844 // SLT fits well with 2 of our 4 pseudo-branches:
2845 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2846 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2847 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2848 // This is accomplished by using a BNEZ with the result of the SLT.
2850 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2851 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2852 // Because only BGE and BLE branch on equality, we can use the
2853 // AcceptsEquality variable to decide when to emit the BEQZ.
2854 // Note that the order of the SLT arguments doesn't change between
2857 // The same applies to the unsigned variants, except that SLTu is used
2860 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2861 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2862 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2863 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2864 Instructions.push_back(SetInst);
2867 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2869 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQL : Mips::BNEL);
2870 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2871 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2872 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2873 Instructions.push_back(BranchInst);
2877 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2878 SmallVectorImpl<MCInst> &Instructions,
2879 const bool IsMips64, const bool Signed) {
2880 if (hasMips32r6()) {
2881 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2885 warnIfNoMacro(IDLoc);
2887 const MCOperand &RsRegOp = Inst.getOperand(0);
2888 assert(RsRegOp.isReg() && "expected register operand kind");
2889 unsigned RsReg = RsRegOp.getReg();
2891 const MCOperand &RtRegOp = Inst.getOperand(1);
2892 assert(RtRegOp.isReg() && "expected register operand kind");
2893 unsigned RtReg = RtRegOp.getReg();
2898 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2899 ZeroReg = Mips::ZERO_64;
2901 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2902 ZeroReg = Mips::ZERO;
2905 bool UseTraps = useTraps();
2907 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2908 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2909 Warning(IDLoc, "dividing zero by zero");
2911 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2913 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2917 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2921 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2926 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2927 Warning(IDLoc, "division by zero");
2930 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2934 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2939 // FIXME: The values for these two BranchTarget variables may be different in
2940 // micromips. These magic numbers need to be removed.
2941 unsigned BranchTargetNoTraps;
2942 unsigned BranchTarget;
2945 BranchTarget = IsMips64 ? 12 : 8;
2946 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2948 BranchTarget = IsMips64 ? 20 : 16;
2949 BranchTargetNoTraps = 8;
2950 // Branch to the li instruction.
2951 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2955 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2958 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2961 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2965 unsigned ATReg = getATReg(IDLoc);
2969 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2971 // Branch to the mflo instruction.
2972 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2973 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2974 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2976 // Branch to the mflo instruction.
2977 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2978 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2982 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2984 // Branch to the mflo instruction.
2985 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2986 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2987 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2989 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2993 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2994 SmallVectorImpl<MCInst> &Instructions) {
2995 if (hasMips32r6() || hasMips64r6()) {
2996 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3000 warnIfNoMacro(IDLoc);
3002 const MCOperand &DstRegOp = Inst.getOperand(0);
3003 assert(DstRegOp.isReg() && "expected register operand kind");
3005 const MCOperand &SrcRegOp = Inst.getOperand(1);
3006 assert(SrcRegOp.isReg() && "expected register operand kind");
3008 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3009 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3011 unsigned DstReg = DstRegOp.getReg();
3012 unsigned SrcReg = SrcRegOp.getReg();
3013 int64_t OffsetValue = OffsetImmOp.getImm();
3015 // NOTE: We always need AT for ULHU, as it is always used as the source
3016 // register for one of the LBu's.
3017 unsigned ATReg = getATReg(IDLoc);
3021 // When the value of offset+1 does not fit in 16 bits, we have to load the
3022 // offset in AT, (D)ADDu the original source register (if there was one), and
3023 // then use AT as the source register for the 2 generated LBu's.
3024 bool LoadedOffsetInAT = false;
3025 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3026 LoadedOffsetInAT = true;
3028 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3029 true, IDLoc, Instructions))
3032 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3033 // because it will make our output more similar to GAS'. For example,
3034 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3035 // instead of just an "ori $1, $9, 32768".
3036 // NOTE: If there is no source register specified in the ULHU, the parser
3037 // will interpret it as $0.
3038 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3039 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3042 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3043 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3044 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3046 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3048 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3049 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3051 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3052 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3055 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3058 TmpInst.setOpcode(Mips::LBu);
3059 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
3060 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
3061 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
3062 Instructions.push_back(TmpInst);
3065 TmpInst.setOpcode(Mips::LBu);
3066 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
3067 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
3068 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
3069 Instructions.push_back(TmpInst);
3072 TmpInst.setOpcode(Mips::SLL);
3073 TmpInst.addOperand(MCOperand::createReg(SllReg));
3074 TmpInst.addOperand(MCOperand::createReg(SllReg));
3075 TmpInst.addOperand(MCOperand::createImm(8));
3076 Instructions.push_back(TmpInst);
3079 TmpInst.setOpcode(Mips::OR);
3080 TmpInst.addOperand(MCOperand::createReg(DstReg));
3081 TmpInst.addOperand(MCOperand::createReg(DstReg));
3082 TmpInst.addOperand(MCOperand::createReg(ATReg));
3083 Instructions.push_back(TmpInst);
3088 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3089 SmallVectorImpl<MCInst> &Instructions) {
3090 if (hasMips32r6() || hasMips64r6()) {
3091 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3095 const MCOperand &DstRegOp = Inst.getOperand(0);
3096 assert(DstRegOp.isReg() && "expected register operand kind");
3098 const MCOperand &SrcRegOp = Inst.getOperand(1);
3099 assert(SrcRegOp.isReg() && "expected register operand kind");
3101 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3102 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3104 unsigned SrcReg = SrcRegOp.getReg();
3105 int64_t OffsetValue = OffsetImmOp.getImm();
3108 // When the value of offset+3 does not fit in 16 bits, we have to load the
3109 // offset in AT, (D)ADDu the original source register (if there was one), and
3110 // then use AT as the source register for the generated LWL and LWR.
3111 bool LoadedOffsetInAT = false;
3112 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3113 ATReg = getATReg(IDLoc);
3116 LoadedOffsetInAT = true;
3118 warnIfNoMacro(IDLoc);
3120 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3121 true, IDLoc, Instructions))
3124 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3125 // because it will make our output more similar to GAS'. For example,
3126 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3127 // instead of just an "ori $1, $9, 32768".
3128 // NOTE: If there is no source register specified in the ULW, the parser
3129 // will interpret it as $0.
3130 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3131 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3134 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3135 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3137 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3138 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3140 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3141 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3144 MCInst LeftLoadInst;
3145 LeftLoadInst.setOpcode(Mips::LWL);
3146 LeftLoadInst.addOperand(DstRegOp);
3147 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3148 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3149 Instructions.push_back(LeftLoadInst);
3151 MCInst RightLoadInst;
3152 RightLoadInst.setOpcode(Mips::LWR);
3153 RightLoadInst.addOperand(DstRegOp);
3154 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3155 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3156 Instructions.push_back(RightLoadInst);
3161 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3162 SmallVectorImpl<MCInst> &Instructions) {
3164 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3165 assert (Inst.getOperand(0).isReg() &&
3166 Inst.getOperand(1).isReg() &&
3167 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3169 unsigned ATReg = Mips::NoRegister;
3170 unsigned FinalDstReg = Mips::NoRegister;
3171 unsigned DstReg = Inst.getOperand(0).getReg();
3172 unsigned SrcReg = Inst.getOperand(1).getReg();
3173 int64_t ImmValue = Inst.getOperand(2).getImm();
3175 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3177 unsigned FinalOpcode = Inst.getOpcode();
3179 if (DstReg == SrcReg) {
3180 ATReg = getATReg(Inst.getLoc());
3183 FinalDstReg = DstReg;
3187 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3188 switch (FinalOpcode) {
3190 llvm_unreachable("unimplemented expansion");
3192 FinalOpcode = Mips::ADD;
3195 FinalOpcode = Mips::ADDu;
3198 FinalOpcode = Mips::AND;
3200 case (Mips::NORImm):
3201 FinalOpcode = Mips::NOR;
3204 FinalOpcode = Mips::OR;
3207 FinalOpcode = Mips::SLT;
3210 FinalOpcode = Mips::SLTu;
3213 FinalOpcode = Mips::XOR;
3220 tmpInst.setLoc(Inst.getLoc());
3221 tmpInst.setOpcode(FinalOpcode);
3222 if (FinalDstReg == Mips::NoRegister) {
3223 tmpInst.addOperand(MCOperand::createReg(DstReg));
3224 tmpInst.addOperand(MCOperand::createReg(DstReg));
3225 tmpInst.addOperand(MCOperand::createReg(SrcReg));
3227 tmpInst.addOperand(MCOperand::createReg(FinalDstReg));
3228 tmpInst.addOperand(MCOperand::createReg(FinalDstReg));
3229 tmpInst.addOperand(MCOperand::createReg(DstReg));
3231 Instructions.push_back(tmpInst);
3237 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3238 SmallVectorImpl<MCInst> &Instructions) {
3240 if (hasShortDelaySlot) {
3241 NopInst.setOpcode(Mips::MOVE16_MM);
3242 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3243 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3245 NopInst.setOpcode(Mips::SLL);
3246 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3247 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3248 NopInst.addOperand(MCOperand::createImm(0));
3250 Instructions.push_back(NopInst);
3253 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3254 unsigned TrgReg, bool Is64Bit,
3255 SmallVectorImpl<MCInst> &Instructions) {
3256 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3260 void MipsAsmParser::createCpRestoreMemOp(
3261 bool IsLoad, int StackOffset, SMLoc IDLoc,
3262 SmallVectorImpl<MCInst> &Instructions) {
3264 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3265 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3266 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3267 MemInst.addOperand(MCOperand::createImm(StackOffset));
3269 // If the offset can not fit into 16 bits, we need to expand.
3270 if (!isInt<16>(StackOffset))
3271 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3273 Instructions.push_back(MemInst);
3276 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3277 // As described by the Mips32r2 spec, the registers Rd and Rs for
3278 // jalr.hb must be different.
3279 unsigned Opcode = Inst.getOpcode();
3281 if (Opcode == Mips::JALR_HB &&
3282 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3283 return Match_RequiresDifferentSrcAndDst;
3285 return Match_Success;
3288 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3289 OperandVector &Operands,
3291 uint64_t &ErrorInfo,
3292 bool MatchingInlineAsm) {
3295 SmallVector<MCInst, 8> Instructions;
3296 unsigned MatchResult =
3297 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3299 switch (MatchResult) {
3300 case Match_Success: {
3301 if (processInstruction(Inst, IDLoc, Instructions))
3303 for (unsigned i = 0; i < Instructions.size(); i++)
3304 Out.EmitInstruction(Instructions[i], STI);
3307 case Match_MissingFeature:
3308 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3310 case Match_InvalidOperand: {
3311 SMLoc ErrorLoc = IDLoc;
3312 if (ErrorInfo != ~0ULL) {
3313 if (ErrorInfo >= Operands.size())
3314 return Error(IDLoc, "too few operands for instruction");
3316 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3317 if (ErrorLoc == SMLoc())
3321 return Error(ErrorLoc, "invalid operand for instruction");
3323 case Match_MnemonicFail:
3324 return Error(IDLoc, "invalid instruction");
3325 case Match_RequiresDifferentSrcAndDst:
3326 return Error(IDLoc, "source and destination must be different");
3329 llvm_unreachable("Implement any new match types added!");
3332 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3333 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3334 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3335 ") without \".set noat\"");
3338 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3339 if (!AssemblerOptions.back()->isMacro())
3340 Warning(Loc, "macro instruction expanded into multiple instructions");
3344 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3345 SMRange Range, bool ShowColors) {
3346 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3347 Range, SMFixIt(Range, FixMsg),
3351 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3354 CC = StringSwitch<unsigned>(Name)
3390 if (!(isABI_N32() || isABI_N64()))
3393 if (12 <= CC && CC <= 15) {
3394 // Name is one of t4-t7
3395 AsmToken RegTok = getLexer().peekTok();
3396 SMRange RegRange = RegTok.getLocRange();
3398 StringRef FixedName = StringSwitch<StringRef>(Name)
3404 assert(FixedName != "" && "Register name is not one of t4-t7.");
3406 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3407 "Did you mean $" + FixedName + "?", RegRange);
3410 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3411 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3412 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3413 if (8 <= CC && CC <= 11)
3417 CC = StringSwitch<unsigned>(Name)
3429 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3432 CC = StringSwitch<unsigned>(Name)
3433 .Case("hwr_cpunum", 0)
3434 .Case("hwr_synci_step", 1)
3436 .Case("hwr_ccres", 3)
3437 .Case("hwr_ulr", 29)
3443 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3445 if (Name[0] == 'f') {
3446 StringRef NumString = Name.substr(1);
3448 if (NumString.getAsInteger(10, IntVal))
3449 return -1; // This is not an integer.
3450 if (IntVal > 31) // Maximum index for fpu register.
3457 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3459 if (Name.startswith("fcc")) {
3460 StringRef NumString = Name.substr(3);
3462 if (NumString.getAsInteger(10, IntVal))
3463 return -1; // This is not an integer.
3464 if (IntVal > 7) // There are only 8 fcc registers.
3471 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3473 if (Name.startswith("ac")) {
3474 StringRef NumString = Name.substr(2);
3476 if (NumString.getAsInteger(10, IntVal))
3477 return -1; // This is not an integer.
3478 if (IntVal > 3) // There are only 3 acc registers.
3485 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3488 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3497 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3500 CC = StringSwitch<unsigned>(Name)
3503 .Case("msaaccess", 2)
3505 .Case("msamodify", 4)
3506 .Case("msarequest", 5)
3508 .Case("msaunmap", 7)
3514 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3515 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3517 reportParseError(Loc,
3518 "pseudo-instruction requires $at, which is not available");
3521 unsigned AT = getReg(
3522 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3526 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3527 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3530 unsigned MipsAsmParser::getGPR(int RegNo) {
3531 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3535 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3537 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3540 return getReg(RegClass, RegNum);
3543 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3544 MCAsmParser &Parser = getParser();
3545 DEBUG(dbgs() << "parseOperand\n");
3547 // Check if the current operand has a custom associated parser, if so, try to
3548 // custom parse the operand, or fallback to the general approach.
3549 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3550 if (ResTy == MatchOperand_Success)
3552 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3553 // there was a match, but an error occurred, in which case, just return that
3554 // the operand parsing failed.
3555 if (ResTy == MatchOperand_ParseFail)
3558 DEBUG(dbgs() << ".. Generic Parser\n");
3560 switch (getLexer().getKind()) {
3562 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3564 case AsmToken::Dollar: {
3565 // Parse the register.
3566 SMLoc S = Parser.getTok().getLoc();
3568 // Almost all registers have been parsed by custom parsers. There is only
3569 // one exception to this. $zero (and it's alias $0) will reach this point
3570 // for div, divu, and similar instructions because it is not an operand
3571 // to the instruction definition but an explicit register. Special case
3572 // this situation for now.
3573 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3576 // Maybe it is a symbol reference.
3577 StringRef Identifier;
3578 if (Parser.parseIdentifier(Identifier))
3581 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3582 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3583 // Otherwise create a symbol reference.
3585 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3587 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3590 // Else drop to expression parsing.
3591 case AsmToken::LParen:
3592 case AsmToken::Minus:
3593 case AsmToken::Plus:
3594 case AsmToken::Integer:
3595 case AsmToken::Tilde:
3596 case AsmToken::String: {
3597 DEBUG(dbgs() << ".. generic integer\n");
3598 OperandMatchResultTy ResTy = parseImm(Operands);
3599 return ResTy != MatchOperand_Success;
3601 case AsmToken::Percent: {
3602 // It is a symbol reference or constant expression.
3603 const MCExpr *IdVal;
3604 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3605 if (parseRelocOperand(IdVal))
3608 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3610 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3612 } // case AsmToken::Percent
3613 } // switch(getLexer().getKind())
3617 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3618 StringRef RelocStr) {
3620 // Check the type of the expression.
3621 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3622 // It's a constant, evaluate reloc value.
3624 switch (getVariantKind(RelocStr)) {
3625 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3626 // Get the 1st 16-bits.
3627 Val = MCE->getValue() & 0xffff;
3629 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3630 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3631 // 16 bits being negative.
3632 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3634 case MCSymbolRefExpr::VK_Mips_HIGHER:
3635 // Get the 3rd 16-bits.
3636 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3638 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3639 // Get the 4th 16-bits.
3640 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3643 report_fatal_error("unsupported reloc value");
3645 return MCConstantExpr::create(Val, getContext());
3648 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3649 // It's a symbol, create a symbolic expression from the symbol.
3650 const MCSymbol *Symbol = &MSRE->getSymbol();
3651 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3652 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3656 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3657 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3659 // Try to create target expression.
3660 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3661 return MipsMCExpr::create(VK, Expr, getContext());
3663 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3664 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3665 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3669 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3670 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3671 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3674 // Just return the original expression.
3678 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3680 switch (Expr->getKind()) {
3681 case MCExpr::Constant:
3683 case MCExpr::SymbolRef:
3684 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3685 case MCExpr::Binary:
3686 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3687 if (!isEvaluated(BE->getLHS()))
3689 return isEvaluated(BE->getRHS());
3692 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3693 case MCExpr::Target:
3699 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3700 MCAsmParser &Parser = getParser();
3701 Parser.Lex(); // Eat the % token.
3702 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3703 if (Tok.isNot(AsmToken::Identifier))
3706 std::string Str = Tok.getIdentifier();
3708 Parser.Lex(); // Eat the identifier.
3709 // Now make an expression from the rest of the operand.
3710 const MCExpr *IdVal;
3713 if (getLexer().getKind() == AsmToken::LParen) {
3715 Parser.Lex(); // Eat the '(' token.
3716 if (getLexer().getKind() == AsmToken::Percent) {
3717 Parser.Lex(); // Eat the % token.
3718 const AsmToken &nextTok = Parser.getTok();
3719 if (nextTok.isNot(AsmToken::Identifier))
3722 Str += nextTok.getIdentifier();
3723 Parser.Lex(); // Eat the identifier.
3724 if (getLexer().getKind() != AsmToken::LParen)
3729 if (getParser().parseParenExpression(IdVal, EndLoc))
3732 while (getLexer().getKind() == AsmToken::RParen)
3733 Parser.Lex(); // Eat the ')' token.
3736 return true; // Parenthesis must follow the relocation operand.
3738 Res = evaluateRelocExpr(IdVal, Str);
3742 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3744 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3745 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3746 if (ResTy == MatchOperand_Success) {
3747 assert(Operands.size() == 1);
3748 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3749 StartLoc = Operand.getStartLoc();
3750 EndLoc = Operand.getEndLoc();
3752 // AFAIK, we only support numeric registers and named GPR's in CFI
3754 // Don't worry about eating tokens before failing. Using an unrecognised
3755 // register is a parse error.
3756 if (Operand.isGPRAsmReg()) {
3757 // Resolve to GPR32 or GPR64 appropriately.
3758 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3761 return (RegNo == (unsigned)-1);
3764 assert(Operands.size() == 0);
3765 return (RegNo == (unsigned)-1);
3768 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3769 MCAsmParser &Parser = getParser();
3772 unsigned NumOfLParen = 0;
3774 while (getLexer().getKind() == AsmToken::LParen) {
3779 switch (getLexer().getKind()) {
3782 case AsmToken::Identifier:
3783 case AsmToken::LParen:
3784 case AsmToken::Integer:
3785 case AsmToken::Minus:
3786 case AsmToken::Plus:
3788 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3790 Result = (getParser().parseExpression(Res));
3791 while (getLexer().getKind() == AsmToken::RParen)
3794 case AsmToken::Percent:
3795 Result = parseRelocOperand(Res);
3800 MipsAsmParser::OperandMatchResultTy
3801 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3802 MCAsmParser &Parser = getParser();
3803 DEBUG(dbgs() << "parseMemOperand\n");
3804 const MCExpr *IdVal = nullptr;
3806 bool isParenExpr = false;
3807 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3808 // First operand is the offset.
3809 S = Parser.getTok().getLoc();
3811 if (getLexer().getKind() == AsmToken::LParen) {
3816 if (getLexer().getKind() != AsmToken::Dollar) {
3817 if (parseMemOffset(IdVal, isParenExpr))
3818 return MatchOperand_ParseFail;
3820 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3821 if (Tok.isNot(AsmToken::LParen)) {
3822 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3823 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3825 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3826 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3827 return MatchOperand_Success;
3829 if (Tok.is(AsmToken::EndOfStatement)) {
3831 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3833 // Zero register assumed, add a memory operand with ZERO as its base.
3834 // "Base" will be managed by k_Memory.
3835 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3838 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3839 return MatchOperand_Success;
3841 Error(Parser.getTok().getLoc(), "'(' expected");
3842 return MatchOperand_ParseFail;
3845 Parser.Lex(); // Eat the '(' token.
3848 Res = parseAnyRegister(Operands);
3849 if (Res != MatchOperand_Success)
3852 if (Parser.getTok().isNot(AsmToken::RParen)) {
3853 Error(Parser.getTok().getLoc(), "')' expected");
3854 return MatchOperand_ParseFail;
3857 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3859 Parser.Lex(); // Eat the ')' token.
3862 IdVal = MCConstantExpr::create(0, getContext());
3864 // Replace the register operand with the memory operand.
3865 std::unique_ptr<MipsOperand> op(
3866 static_cast<MipsOperand *>(Operands.back().release()));
3867 // Remove the register from the operands.
3868 // "op" will be managed by k_Memory.
3869 Operands.pop_back();
3870 // Add the memory operand.
3871 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3873 if (IdVal->evaluateAsAbsolute(Imm))
3874 IdVal = MCConstantExpr::create(Imm, getContext());
3875 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3876 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3880 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3881 return MatchOperand_Success;
3884 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3885 MCAsmParser &Parser = getParser();
3886 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3888 SMLoc S = Parser.getTok().getLoc();
3890 if (Sym->isVariable())
3891 Expr = Sym->getVariableValue();
3894 if (Expr->getKind() == MCExpr::SymbolRef) {
3895 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3896 StringRef DefSymbol = Ref->getSymbol().getName();
3897 if (DefSymbol.startswith("$")) {
3898 OperandMatchResultTy ResTy =
3899 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3900 if (ResTy == MatchOperand_Success) {
3903 } else if (ResTy == MatchOperand_ParseFail)
3904 llvm_unreachable("Should never ParseFail");
3907 } else if (Expr->getKind() == MCExpr::Constant) {
3909 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3911 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3918 MipsAsmParser::OperandMatchResultTy
3919 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3920 StringRef Identifier,
3922 int Index = matchCPURegisterName(Identifier);
3924 Operands.push_back(MipsOperand::createGPRReg(
3925 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3926 return MatchOperand_Success;
3929 Index = matchHWRegsRegisterName(Identifier);
3931 Operands.push_back(MipsOperand::createHWRegsReg(
3932 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3933 return MatchOperand_Success;
3936 Index = matchFPURegisterName(Identifier);
3938 Operands.push_back(MipsOperand::createFGRReg(
3939 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3940 return MatchOperand_Success;
3943 Index = matchFCCRegisterName(Identifier);
3945 Operands.push_back(MipsOperand::createFCCReg(
3946 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3947 return MatchOperand_Success;
3950 Index = matchACRegisterName(Identifier);
3952 Operands.push_back(MipsOperand::createACCReg(
3953 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3954 return MatchOperand_Success;
3957 Index = matchMSA128RegisterName(Identifier);
3959 Operands.push_back(MipsOperand::createMSA128Reg(
3960 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3961 return MatchOperand_Success;
3964 Index = matchMSA128CtrlRegisterName(Identifier);
3966 Operands.push_back(MipsOperand::createMSACtrlReg(
3967 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3968 return MatchOperand_Success;
3971 return MatchOperand_NoMatch;
3974 MipsAsmParser::OperandMatchResultTy
3975 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3976 MCAsmParser &Parser = getParser();
3977 auto Token = Parser.getLexer().peekTok(false);
3979 if (Token.is(AsmToken::Identifier)) {
3980 DEBUG(dbgs() << ".. identifier\n");
3981 StringRef Identifier = Token.getIdentifier();
3982 OperandMatchResultTy ResTy =
3983 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3985 } else if (Token.is(AsmToken::Integer)) {
3986 DEBUG(dbgs() << ".. integer\n");
3987 Operands.push_back(MipsOperand::createNumericReg(
3988 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3990 return MatchOperand_Success;
3993 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3995 return MatchOperand_NoMatch;
3998 MipsAsmParser::OperandMatchResultTy
3999 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4000 MCAsmParser &Parser = getParser();
4001 DEBUG(dbgs() << "parseAnyRegister\n");
4003 auto Token = Parser.getTok();
4005 SMLoc S = Token.getLoc();
4007 if (Token.isNot(AsmToken::Dollar)) {
4008 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4009 if (Token.is(AsmToken::Identifier)) {
4010 if (searchSymbolAlias(Operands))
4011 return MatchOperand_Success;
4013 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4014 return MatchOperand_NoMatch;
4016 DEBUG(dbgs() << ".. $\n");
4018 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4019 if (ResTy == MatchOperand_Success) {
4021 Parser.Lex(); // identifier
4026 MipsAsmParser::OperandMatchResultTy
4027 MipsAsmParser::parseImm(OperandVector &Operands) {
4028 MCAsmParser &Parser = getParser();
4029 switch (getLexer().getKind()) {
4031 return MatchOperand_NoMatch;
4032 case AsmToken::LParen:
4033 case AsmToken::Minus:
4034 case AsmToken::Plus:
4035 case AsmToken::Integer:
4036 case AsmToken::Tilde:
4037 case AsmToken::String:
4041 const MCExpr *IdVal;
4042 SMLoc S = Parser.getTok().getLoc();
4043 if (getParser().parseExpression(IdVal))
4044 return MatchOperand_ParseFail;
4046 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4047 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4048 return MatchOperand_Success;
4051 MipsAsmParser::OperandMatchResultTy
4052 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4053 MCAsmParser &Parser = getParser();
4054 DEBUG(dbgs() << "parseJumpTarget\n");
4056 SMLoc S = getLexer().getLoc();
4058 // Integers and expressions are acceptable
4059 OperandMatchResultTy ResTy = parseImm(Operands);
4060 if (ResTy != MatchOperand_NoMatch)
4063 // Registers are a valid target and have priority over symbols.
4064 ResTy = parseAnyRegister(Operands);
4065 if (ResTy != MatchOperand_NoMatch)
4068 const MCExpr *Expr = nullptr;
4069 if (Parser.parseExpression(Expr)) {
4070 // We have no way of knowing if a symbol was consumed so we must ParseFail
4071 return MatchOperand_ParseFail;
4074 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4075 return MatchOperand_Success;
4078 MipsAsmParser::OperandMatchResultTy
4079 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4080 MCAsmParser &Parser = getParser();
4081 const MCExpr *IdVal;
4082 // If the first token is '$' we may have register operand.
4083 if (Parser.getTok().is(AsmToken::Dollar))
4084 return MatchOperand_NoMatch;
4085 SMLoc S = Parser.getTok().getLoc();
4086 if (getParser().parseExpression(IdVal))
4087 return MatchOperand_ParseFail;
4088 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4089 assert(MCE && "Unexpected MCExpr type.");
4090 int64_t Val = MCE->getValue();
4091 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4092 Operands.push_back(MipsOperand::CreateImm(
4093 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4094 return MatchOperand_Success;
4097 MipsAsmParser::OperandMatchResultTy
4098 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4099 MCAsmParser &Parser = getParser();
4100 switch (getLexer().getKind()) {
4102 return MatchOperand_NoMatch;
4103 case AsmToken::LParen:
4104 case AsmToken::Plus:
4105 case AsmToken::Minus:
4106 case AsmToken::Integer:
4111 SMLoc S = Parser.getTok().getLoc();
4113 if (getParser().parseExpression(Expr))
4114 return MatchOperand_ParseFail;
4117 if (!Expr->evaluateAsAbsolute(Val)) {
4118 Error(S, "expected immediate value");
4119 return MatchOperand_ParseFail;
4122 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4123 // and because the CPU always adds one to the immediate field, the allowed
4124 // range becomes 1..4. We'll only check the range here and will deal
4125 // with the addition/subtraction when actually decoding/encoding
4127 if (Val < 1 || Val > 4) {
4128 Error(S, "immediate not in range (1..4)");
4129 return MatchOperand_ParseFail;
4133 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4134 return MatchOperand_Success;
4137 MipsAsmParser::OperandMatchResultTy
4138 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4139 MCAsmParser &Parser = getParser();
4140 SmallVector<unsigned, 10> Regs;
4142 unsigned PrevReg = Mips::NoRegister;
4143 bool RegRange = false;
4144 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4146 if (Parser.getTok().isNot(AsmToken::Dollar))
4147 return MatchOperand_ParseFail;
4149 SMLoc S = Parser.getTok().getLoc();
4150 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4151 SMLoc E = getLexer().getLoc();
4152 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4153 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4155 // Remove last register operand because registers from register range
4156 // should be inserted first.
4157 if (RegNo == Mips::RA) {
4158 Regs.push_back(RegNo);
4160 unsigned TmpReg = PrevReg + 1;
4161 while (TmpReg <= RegNo) {
4162 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4163 Error(E, "invalid register operand");
4164 return MatchOperand_ParseFail;
4168 Regs.push_back(TmpReg++);
4174 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4175 (RegNo != Mips::RA)) {
4176 Error(E, "$16 or $31 expected");
4177 return MatchOperand_ParseFail;
4178 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4179 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4180 Error(E, "invalid register operand");
4181 return MatchOperand_ParseFail;
4182 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4183 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4184 Error(E, "consecutive register numbers expected");
4185 return MatchOperand_ParseFail;
4188 Regs.push_back(RegNo);
4191 if (Parser.getTok().is(AsmToken::Minus))
4194 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4195 !Parser.getTok().isNot(AsmToken::Comma)) {
4196 Error(E, "',' or '-' expected");
4197 return MatchOperand_ParseFail;
4200 Lex(); // Consume comma or minus
4201 if (Parser.getTok().isNot(AsmToken::Dollar))
4207 SMLoc E = Parser.getTok().getLoc();
4208 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4209 parseMemOperand(Operands);
4210 return MatchOperand_Success;
4213 MipsAsmParser::OperandMatchResultTy
4214 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4215 MCAsmParser &Parser = getParser();
4217 SMLoc S = Parser.getTok().getLoc();
4218 if (parseAnyRegister(Operands) != MatchOperand_Success)
4219 return MatchOperand_ParseFail;
4221 SMLoc E = Parser.getTok().getLoc();
4222 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4223 unsigned Reg = Op.getGPR32Reg();
4224 Operands.pop_back();
4225 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4226 return MatchOperand_Success;
4229 MipsAsmParser::OperandMatchResultTy
4230 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4231 MCAsmParser &Parser = getParser();
4232 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4233 SmallVector<unsigned, 10> Regs;
4235 if (Parser.getTok().isNot(AsmToken::Dollar))
4236 return MatchOperand_ParseFail;
4238 SMLoc S = Parser.getTok().getLoc();
4240 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4241 return MatchOperand_ParseFail;
4243 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4244 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4245 Regs.push_back(RegNo);
4247 SMLoc E = Parser.getTok().getLoc();
4248 if (Parser.getTok().isNot(AsmToken::Comma)) {
4249 Error(E, "',' expected");
4250 return MatchOperand_ParseFail;
4256 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4257 return MatchOperand_ParseFail;
4259 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4260 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4261 Regs.push_back(RegNo);
4263 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4265 return MatchOperand_Success;
4268 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4270 MCSymbolRefExpr::VariantKind VK =
4271 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4272 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4273 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4274 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4275 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4276 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4277 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4278 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4279 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4280 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4281 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4282 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4283 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4284 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4285 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4286 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4287 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4288 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4289 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4290 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4291 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4292 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4293 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4294 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4295 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4296 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4297 .Default(MCSymbolRefExpr::VK_None);
4299 assert(VK != MCSymbolRefExpr::VK_None);
4304 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4306 /// ::= '(', register, ')'
4307 /// handle it before we iterate so we don't get tripped up by the lack of
4309 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4310 MCAsmParser &Parser = getParser();
4311 if (getLexer().is(AsmToken::LParen)) {
4313 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4315 if (parseOperand(Operands, Name)) {
4316 SMLoc Loc = getLexer().getLoc();
4317 Parser.eatToEndOfStatement();
4318 return Error(Loc, "unexpected token in argument list");
4320 if (Parser.getTok().isNot(AsmToken::RParen)) {
4321 SMLoc Loc = getLexer().getLoc();
4322 Parser.eatToEndOfStatement();
4323 return Error(Loc, "unexpected token, expected ')'");
4326 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4332 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4333 /// either one of these.
4334 /// ::= '[', register, ']'
4335 /// ::= '[', integer, ']'
4336 /// handle it before we iterate so we don't get tripped up by the lack of
4338 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4339 OperandVector &Operands) {
4340 MCAsmParser &Parser = getParser();
4341 if (getLexer().is(AsmToken::LBrac)) {
4343 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4345 if (parseOperand(Operands, Name)) {
4346 SMLoc Loc = getLexer().getLoc();
4347 Parser.eatToEndOfStatement();
4348 return Error(Loc, "unexpected token in argument list");
4350 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4351 SMLoc Loc = getLexer().getLoc();
4352 Parser.eatToEndOfStatement();
4353 return Error(Loc, "unexpected token, expected ']'");
4356 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4362 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4363 SMLoc NameLoc, OperandVector &Operands) {
4364 MCAsmParser &Parser = getParser();
4365 DEBUG(dbgs() << "ParseInstruction\n");
4367 // We have reached first instruction, module directive are now forbidden.
4368 getTargetStreamer().forbidModuleDirective();
4370 // Check if we have valid mnemonic
4371 if (!mnemonicIsValid(Name, 0)) {
4372 Parser.eatToEndOfStatement();
4373 return Error(NameLoc, "unknown instruction");
4375 // First operand in MCInst is instruction mnemonic.
4376 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4378 // Read the remaining operands.
4379 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4380 // Read the first operand.
4381 if (parseOperand(Operands, Name)) {
4382 SMLoc Loc = getLexer().getLoc();
4383 Parser.eatToEndOfStatement();
4384 return Error(Loc, "unexpected token in argument list");
4386 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4388 // AFAIK, parenthesis suffixes are never on the first operand
4390 while (getLexer().is(AsmToken::Comma)) {
4391 Parser.Lex(); // Eat the comma.
4392 // Parse and remember the operand.
4393 if (parseOperand(Operands, Name)) {
4394 SMLoc Loc = getLexer().getLoc();
4395 Parser.eatToEndOfStatement();
4396 return Error(Loc, "unexpected token in argument list");
4398 // Parse bracket and parenthesis suffixes before we iterate
4399 if (getLexer().is(AsmToken::LBrac)) {
4400 if (parseBracketSuffix(Name, Operands))
4402 } else if (getLexer().is(AsmToken::LParen) &&
4403 parseParenSuffix(Name, Operands))
4407 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4408 SMLoc Loc = getLexer().getLoc();
4409 Parser.eatToEndOfStatement();
4410 return Error(Loc, "unexpected token in argument list");
4412 Parser.Lex(); // Consume the EndOfStatement.
4416 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4417 MCAsmParser &Parser = getParser();
4418 SMLoc Loc = getLexer().getLoc();
4419 Parser.eatToEndOfStatement();
4420 return Error(Loc, ErrorMsg);
4423 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4424 return Error(Loc, ErrorMsg);
4427 bool MipsAsmParser::parseSetNoAtDirective() {
4428 MCAsmParser &Parser = getParser();
4429 // Line should look like: ".set noat".
4431 // Set the $at register to $0.
4432 AssemblerOptions.back()->setATRegIndex(0);
4434 Parser.Lex(); // Eat "noat".
4436 // If this is not the end of the statement, report an error.
4437 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4438 reportParseError("unexpected token, expected end of statement");
4442 getTargetStreamer().emitDirectiveSetNoAt();
4443 Parser.Lex(); // Consume the EndOfStatement.
4447 bool MipsAsmParser::parseSetAtDirective() {
4448 // Line can be: ".set at", which sets $at to $1
4449 // or ".set at=$reg", which sets $at to $reg.
4450 MCAsmParser &Parser = getParser();
4451 Parser.Lex(); // Eat "at".
4453 if (getLexer().is(AsmToken::EndOfStatement)) {
4454 // No register was specified, so we set $at to $1.
4455 AssemblerOptions.back()->setATRegIndex(1);
4457 getTargetStreamer().emitDirectiveSetAt();
4458 Parser.Lex(); // Consume the EndOfStatement.
4462 if (getLexer().isNot(AsmToken::Equal)) {
4463 reportParseError("unexpected token, expected equals sign");
4466 Parser.Lex(); // Eat "=".
4468 if (getLexer().isNot(AsmToken::Dollar)) {
4469 if (getLexer().is(AsmToken::EndOfStatement)) {
4470 reportParseError("no register specified");
4473 reportParseError("unexpected token, expected dollar sign '$'");
4477 Parser.Lex(); // Eat "$".
4479 // Find out what "reg" is.
4481 const AsmToken &Reg = Parser.getTok();
4482 if (Reg.is(AsmToken::Identifier)) {
4483 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4484 } else if (Reg.is(AsmToken::Integer)) {
4485 AtRegNo = Reg.getIntVal();
4487 reportParseError("unexpected token, expected identifier or integer");
4491 // Check if $reg is a valid register. If it is, set $at to $reg.
4492 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4493 reportParseError("invalid register");
4496 Parser.Lex(); // Eat "reg".
4498 // If this is not the end of the statement, report an error.
4499 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4500 reportParseError("unexpected token, expected end of statement");
4504 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4506 Parser.Lex(); // Consume the EndOfStatement.
4510 bool MipsAsmParser::parseSetReorderDirective() {
4511 MCAsmParser &Parser = getParser();
4513 // If this is not the end of the statement, report an error.
4514 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4515 reportParseError("unexpected token, expected end of statement");
4518 AssemblerOptions.back()->setReorder();
4519 getTargetStreamer().emitDirectiveSetReorder();
4520 Parser.Lex(); // Consume the EndOfStatement.
4524 bool MipsAsmParser::parseSetNoReorderDirective() {
4525 MCAsmParser &Parser = getParser();
4527 // If this is not the end of the statement, report an error.
4528 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4529 reportParseError("unexpected token, expected end of statement");
4532 AssemblerOptions.back()->setNoReorder();
4533 getTargetStreamer().emitDirectiveSetNoReorder();
4534 Parser.Lex(); // Consume the EndOfStatement.
4538 bool MipsAsmParser::parseSetMacroDirective() {
4539 MCAsmParser &Parser = getParser();
4541 // If this is not the end of the statement, report an error.
4542 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4543 reportParseError("unexpected token, expected end of statement");
4546 AssemblerOptions.back()->setMacro();
4547 getTargetStreamer().emitDirectiveSetMacro();
4548 Parser.Lex(); // Consume the EndOfStatement.
4552 bool MipsAsmParser::parseSetNoMacroDirective() {
4553 MCAsmParser &Parser = getParser();
4555 // If this is not the end of the statement, report an error.
4556 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4557 reportParseError("unexpected token, expected end of statement");
4560 if (AssemblerOptions.back()->isReorder()) {
4561 reportParseError("`noreorder' must be set before `nomacro'");
4564 AssemblerOptions.back()->setNoMacro();
4565 getTargetStreamer().emitDirectiveSetNoMacro();
4566 Parser.Lex(); // Consume the EndOfStatement.
4570 bool MipsAsmParser::parseSetMsaDirective() {
4571 MCAsmParser &Parser = getParser();
4574 // If this is not the end of the statement, report an error.
4575 if (getLexer().isNot(AsmToken::EndOfStatement))
4576 return reportParseError("unexpected token, expected end of statement");
4578 setFeatureBits(Mips::FeatureMSA, "msa");
4579 getTargetStreamer().emitDirectiveSetMsa();
4583 bool MipsAsmParser::parseSetNoMsaDirective() {
4584 MCAsmParser &Parser = getParser();
4587 // If this is not the end of the statement, report an error.
4588 if (getLexer().isNot(AsmToken::EndOfStatement))
4589 return reportParseError("unexpected token, expected end of statement");
4591 clearFeatureBits(Mips::FeatureMSA, "msa");
4592 getTargetStreamer().emitDirectiveSetNoMsa();
4596 bool MipsAsmParser::parseSetNoDspDirective() {
4597 MCAsmParser &Parser = getParser();
4598 Parser.Lex(); // Eat "nodsp".
4600 // If this is not the end of the statement, report an error.
4601 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4602 reportParseError("unexpected token, expected end of statement");
4606 clearFeatureBits(Mips::FeatureDSP, "dsp");
4607 getTargetStreamer().emitDirectiveSetNoDsp();
4611 bool MipsAsmParser::parseSetMips16Directive() {
4612 MCAsmParser &Parser = getParser();
4613 Parser.Lex(); // Eat "mips16".
4615 // If this is not the end of the statement, report an error.
4616 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4617 reportParseError("unexpected token, expected end of statement");
4621 setFeatureBits(Mips::FeatureMips16, "mips16");
4622 getTargetStreamer().emitDirectiveSetMips16();
4623 Parser.Lex(); // Consume the EndOfStatement.
4627 bool MipsAsmParser::parseSetNoMips16Directive() {
4628 MCAsmParser &Parser = getParser();
4629 Parser.Lex(); // Eat "nomips16".
4631 // If this is not the end of the statement, report an error.
4632 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4633 reportParseError("unexpected token, expected end of statement");
4637 clearFeatureBits(Mips::FeatureMips16, "mips16");
4638 getTargetStreamer().emitDirectiveSetNoMips16();
4639 Parser.Lex(); // Consume the EndOfStatement.
4643 bool MipsAsmParser::parseSetFpDirective() {
4644 MCAsmParser &Parser = getParser();
4645 MipsABIFlagsSection::FpABIKind FpAbiVal;
4646 // Line can be: .set fp=32
4649 Parser.Lex(); // Eat fp token
4650 AsmToken Tok = Parser.getTok();
4651 if (Tok.isNot(AsmToken::Equal)) {
4652 reportParseError("unexpected token, expected equals sign '='");
4655 Parser.Lex(); // Eat '=' token.
4656 Tok = Parser.getTok();
4658 if (!parseFpABIValue(FpAbiVal, ".set"))
4661 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4662 reportParseError("unexpected token, expected end of statement");
4665 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4666 Parser.Lex(); // Consume the EndOfStatement.
4670 bool MipsAsmParser::parseSetOddSPRegDirective() {
4671 MCAsmParser &Parser = getParser();
4673 Parser.Lex(); // Eat "oddspreg".
4674 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4675 reportParseError("unexpected token, expected end of statement");
4679 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4680 getTargetStreamer().emitDirectiveSetOddSPReg();
4684 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4685 MCAsmParser &Parser = getParser();
4687 Parser.Lex(); // Eat "nooddspreg".
4688 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4689 reportParseError("unexpected token, expected end of statement");
4693 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4694 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4698 bool MipsAsmParser::parseSetPopDirective() {
4699 MCAsmParser &Parser = getParser();
4700 SMLoc Loc = getLexer().getLoc();
4703 if (getLexer().isNot(AsmToken::EndOfStatement))
4704 return reportParseError("unexpected token, expected end of statement");
4706 // Always keep an element on the options "stack" to prevent the user
4707 // from changing the initial options. This is how we remember them.
4708 if (AssemblerOptions.size() == 2)
4709 return reportParseError(Loc, ".set pop with no .set push");
4711 AssemblerOptions.pop_back();
4712 setAvailableFeatures(
4713 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4714 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4716 getTargetStreamer().emitDirectiveSetPop();
4720 bool MipsAsmParser::parseSetPushDirective() {
4721 MCAsmParser &Parser = getParser();
4723 if (getLexer().isNot(AsmToken::EndOfStatement))
4724 return reportParseError("unexpected token, expected end of statement");
4726 // Create a copy of the current assembler options environment and push it.
4727 AssemblerOptions.push_back(
4728 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4730 getTargetStreamer().emitDirectiveSetPush();
4734 bool MipsAsmParser::parseSetSoftFloatDirective() {
4735 MCAsmParser &Parser = getParser();
4737 if (getLexer().isNot(AsmToken::EndOfStatement))
4738 return reportParseError("unexpected token, expected end of statement");
4740 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4741 getTargetStreamer().emitDirectiveSetSoftFloat();
4745 bool MipsAsmParser::parseSetHardFloatDirective() {
4746 MCAsmParser &Parser = getParser();
4748 if (getLexer().isNot(AsmToken::EndOfStatement))
4749 return reportParseError("unexpected token, expected end of statement");
4751 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4752 getTargetStreamer().emitDirectiveSetHardFloat();
4756 bool MipsAsmParser::parseSetAssignment() {
4758 const MCExpr *Value;
4759 MCAsmParser &Parser = getParser();
4761 if (Parser.parseIdentifier(Name))
4762 reportParseError("expected identifier after .set");
4764 if (getLexer().isNot(AsmToken::Comma))
4765 return reportParseError("unexpected token, expected comma");
4768 if (Parser.parseExpression(Value))
4769 return reportParseError("expected valid expression after comma");
4771 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4772 Sym->setVariableValue(Value);
4777 bool MipsAsmParser::parseSetMips0Directive() {
4778 MCAsmParser &Parser = getParser();
4780 if (getLexer().isNot(AsmToken::EndOfStatement))
4781 return reportParseError("unexpected token, expected end of statement");
4783 // Reset assembler options to their initial values.
4784 setAvailableFeatures(
4785 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4786 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4787 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4789 getTargetStreamer().emitDirectiveSetMips0();
4793 bool MipsAsmParser::parseSetArchDirective() {
4794 MCAsmParser &Parser = getParser();
4796 if (getLexer().isNot(AsmToken::Equal))
4797 return reportParseError("unexpected token, expected equals sign");
4801 if (Parser.parseIdentifier(Arch))
4802 return reportParseError("expected arch identifier");
4804 StringRef ArchFeatureName =
4805 StringSwitch<StringRef>(Arch)
4806 .Case("mips1", "mips1")
4807 .Case("mips2", "mips2")
4808 .Case("mips3", "mips3")
4809 .Case("mips4", "mips4")
4810 .Case("mips5", "mips5")
4811 .Case("mips32", "mips32")
4812 .Case("mips32r2", "mips32r2")
4813 .Case("mips32r3", "mips32r3")
4814 .Case("mips32r5", "mips32r5")
4815 .Case("mips32r6", "mips32r6")
4816 .Case("mips64", "mips64")
4817 .Case("mips64r2", "mips64r2")
4818 .Case("mips64r3", "mips64r3")
4819 .Case("mips64r5", "mips64r5")
4820 .Case("mips64r6", "mips64r6")
4821 .Case("cnmips", "cnmips")
4822 .Case("r4000", "mips3") // This is an implementation of Mips3.
4825 if (ArchFeatureName.empty())
4826 return reportParseError("unsupported architecture");
4828 selectArch(ArchFeatureName);
4829 getTargetStreamer().emitDirectiveSetArch(Arch);
4833 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4834 MCAsmParser &Parser = getParser();
4836 if (getLexer().isNot(AsmToken::EndOfStatement))
4837 return reportParseError("unexpected token, expected end of statement");
4841 llvm_unreachable("Unimplemented feature");
4842 case Mips::FeatureDSP:
4843 setFeatureBits(Mips::FeatureDSP, "dsp");
4844 getTargetStreamer().emitDirectiveSetDsp();
4846 case Mips::FeatureMicroMips:
4847 getTargetStreamer().emitDirectiveSetMicroMips();
4849 case Mips::FeatureMips1:
4850 selectArch("mips1");
4851 getTargetStreamer().emitDirectiveSetMips1();
4853 case Mips::FeatureMips2:
4854 selectArch("mips2");
4855 getTargetStreamer().emitDirectiveSetMips2();
4857 case Mips::FeatureMips3:
4858 selectArch("mips3");
4859 getTargetStreamer().emitDirectiveSetMips3();
4861 case Mips::FeatureMips4:
4862 selectArch("mips4");
4863 getTargetStreamer().emitDirectiveSetMips4();
4865 case Mips::FeatureMips5:
4866 selectArch("mips5");
4867 getTargetStreamer().emitDirectiveSetMips5();
4869 case Mips::FeatureMips32:
4870 selectArch("mips32");
4871 getTargetStreamer().emitDirectiveSetMips32();
4873 case Mips::FeatureMips32r2:
4874 selectArch("mips32r2");
4875 getTargetStreamer().emitDirectiveSetMips32R2();
4877 case Mips::FeatureMips32r3:
4878 selectArch("mips32r3");
4879 getTargetStreamer().emitDirectiveSetMips32R3();
4881 case Mips::FeatureMips32r5:
4882 selectArch("mips32r5");
4883 getTargetStreamer().emitDirectiveSetMips32R5();
4885 case Mips::FeatureMips32r6:
4886 selectArch("mips32r6");
4887 getTargetStreamer().emitDirectiveSetMips32R6();
4889 case Mips::FeatureMips64:
4890 selectArch("mips64");
4891 getTargetStreamer().emitDirectiveSetMips64();
4893 case Mips::FeatureMips64r2:
4894 selectArch("mips64r2");
4895 getTargetStreamer().emitDirectiveSetMips64R2();
4897 case Mips::FeatureMips64r3:
4898 selectArch("mips64r3");
4899 getTargetStreamer().emitDirectiveSetMips64R3();
4901 case Mips::FeatureMips64r5:
4902 selectArch("mips64r5");
4903 getTargetStreamer().emitDirectiveSetMips64R5();
4905 case Mips::FeatureMips64r6:
4906 selectArch("mips64r6");
4907 getTargetStreamer().emitDirectiveSetMips64R6();
4913 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4914 MCAsmParser &Parser = getParser();
4915 if (getLexer().isNot(AsmToken::Comma)) {
4916 SMLoc Loc = getLexer().getLoc();
4917 Parser.eatToEndOfStatement();
4918 return Error(Loc, ErrorStr);
4921 Parser.Lex(); // Eat the comma.
4925 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4926 // In this class, it is only used for .cprestore.
4927 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4928 // MipsTargetELFStreamer and MipsAsmParser.
4929 bool MipsAsmParser::isPicAndNotNxxAbi() {
4930 return inPicMode() && !(isABI_N32() || isABI_N64());
4933 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4934 if (AssemblerOptions.back()->isReorder())
4935 Warning(Loc, ".cpload should be inside a noreorder section");
4937 if (inMips16Mode()) {
4938 reportParseError(".cpload is not supported in Mips16 mode");
4942 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4943 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4944 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4945 reportParseError("expected register containing function address");
4949 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4950 if (!RegOpnd.isGPRAsmReg()) {
4951 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4955 // If this is not the end of the statement, report an error.
4956 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4957 reportParseError("unexpected token, expected end of statement");
4961 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4965 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4966 MCAsmParser &Parser = getParser();
4968 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4969 // is used in non-PIC mode.
4971 if (inMips16Mode()) {
4972 reportParseError(".cprestore is not supported in Mips16 mode");
4976 // Get the stack offset value.
4977 const MCExpr *StackOffset;
4978 int64_t StackOffsetVal;
4979 if (Parser.parseExpression(StackOffset)) {
4980 reportParseError("expected stack offset value");
4984 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4985 reportParseError("stack offset is not an absolute expression");
4989 if (StackOffsetVal < 0) {
4990 Warning(Loc, ".cprestore with negative stack offset has no effect");
4991 IsCpRestoreSet = false;
4993 IsCpRestoreSet = true;
4994 CpRestoreOffset = StackOffsetVal;
4997 // If this is not the end of the statement, report an error.
4998 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4999 reportParseError("unexpected token, expected end of statement");
5003 // Store the $gp on the stack.
5004 SmallVector<MCInst, 3> StoreInsts;
5005 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5008 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
5009 Parser.Lex(); // Consume the EndOfStatement.
5013 bool MipsAsmParser::parseDirectiveCPSetup() {
5014 MCAsmParser &Parser = getParser();
5017 bool SaveIsReg = true;
5019 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5020 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5021 if (ResTy == MatchOperand_NoMatch) {
5022 reportParseError("expected register containing function address");
5023 Parser.eatToEndOfStatement();
5027 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5028 if (!FuncRegOpnd.isGPRAsmReg()) {
5029 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5030 Parser.eatToEndOfStatement();
5034 FuncReg = FuncRegOpnd.getGPR32Reg();
5037 if (!eatComma("unexpected token, expected comma"))
5040 ResTy = parseAnyRegister(TmpReg);
5041 if (ResTy == MatchOperand_NoMatch) {
5042 const MCExpr *OffsetExpr;
5044 SMLoc ExprLoc = getLexer().getLoc();
5046 if (Parser.parseExpression(OffsetExpr) ||
5047 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5048 reportParseError(ExprLoc, "expected save register or stack offset");
5049 Parser.eatToEndOfStatement();
5056 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5057 if (!SaveOpnd.isGPRAsmReg()) {
5058 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5059 Parser.eatToEndOfStatement();
5062 Save = SaveOpnd.getGPR32Reg();
5065 if (!eatComma("unexpected token, expected comma"))
5069 if (Parser.parseExpression(Expr)) {
5070 reportParseError("expected expression");
5074 if (Expr->getKind() != MCExpr::SymbolRef) {
5075 reportParseError("expected symbol");
5078 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5080 CpSaveLocation = Save;
5081 CpSaveLocationIsRegister = SaveIsReg;
5083 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5088 bool MipsAsmParser::parseDirectiveCPReturn() {
5089 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5090 CpSaveLocationIsRegister);
5094 bool MipsAsmParser::parseDirectiveNaN() {
5095 MCAsmParser &Parser = getParser();
5096 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5097 const AsmToken &Tok = Parser.getTok();
5099 if (Tok.getString() == "2008") {
5101 getTargetStreamer().emitDirectiveNaN2008();
5103 } else if (Tok.getString() == "legacy") {
5105 getTargetStreamer().emitDirectiveNaNLegacy();
5109 // If we don't recognize the option passed to the .nan
5110 // directive (e.g. no option or unknown option), emit an error.
5111 reportParseError("invalid option in .nan directive");
5115 bool MipsAsmParser::parseDirectiveSet() {
5116 MCAsmParser &Parser = getParser();
5117 // Get the next token.
5118 const AsmToken &Tok = Parser.getTok();
5120 if (Tok.getString() == "noat") {
5121 return parseSetNoAtDirective();
5122 } else if (Tok.getString() == "at") {
5123 return parseSetAtDirective();
5124 } else if (Tok.getString() == "arch") {
5125 return parseSetArchDirective();
5126 } else if (Tok.getString() == "fp") {
5127 return parseSetFpDirective();
5128 } else if (Tok.getString() == "oddspreg") {
5129 return parseSetOddSPRegDirective();
5130 } else if (Tok.getString() == "nooddspreg") {
5131 return parseSetNoOddSPRegDirective();
5132 } else if (Tok.getString() == "pop") {
5133 return parseSetPopDirective();
5134 } else if (Tok.getString() == "push") {
5135 return parseSetPushDirective();
5136 } else if (Tok.getString() == "reorder") {
5137 return parseSetReorderDirective();
5138 } else if (Tok.getString() == "noreorder") {
5139 return parseSetNoReorderDirective();
5140 } else if (Tok.getString() == "macro") {
5141 return parseSetMacroDirective();
5142 } else if (Tok.getString() == "nomacro") {
5143 return parseSetNoMacroDirective();
5144 } else if (Tok.getString() == "mips16") {
5145 return parseSetMips16Directive();
5146 } else if (Tok.getString() == "nomips16") {
5147 return parseSetNoMips16Directive();
5148 } else if (Tok.getString() == "nomicromips") {
5149 getTargetStreamer().emitDirectiveSetNoMicroMips();
5150 Parser.eatToEndOfStatement();
5152 } else if (Tok.getString() == "micromips") {
5153 return parseSetFeature(Mips::FeatureMicroMips);
5154 } else if (Tok.getString() == "mips0") {
5155 return parseSetMips0Directive();
5156 } else if (Tok.getString() == "mips1") {
5157 return parseSetFeature(Mips::FeatureMips1);
5158 } else if (Tok.getString() == "mips2") {
5159 return parseSetFeature(Mips::FeatureMips2);
5160 } else if (Tok.getString() == "mips3") {
5161 return parseSetFeature(Mips::FeatureMips3);
5162 } else if (Tok.getString() == "mips4") {
5163 return parseSetFeature(Mips::FeatureMips4);
5164 } else if (Tok.getString() == "mips5") {
5165 return parseSetFeature(Mips::FeatureMips5);
5166 } else if (Tok.getString() == "mips32") {
5167 return parseSetFeature(Mips::FeatureMips32);
5168 } else if (Tok.getString() == "mips32r2") {
5169 return parseSetFeature(Mips::FeatureMips32r2);
5170 } else if (Tok.getString() == "mips32r3") {
5171 return parseSetFeature(Mips::FeatureMips32r3);
5172 } else if (Tok.getString() == "mips32r5") {
5173 return parseSetFeature(Mips::FeatureMips32r5);
5174 } else if (Tok.getString() == "mips32r6") {
5175 return parseSetFeature(Mips::FeatureMips32r6);
5176 } else if (Tok.getString() == "mips64") {
5177 return parseSetFeature(Mips::FeatureMips64);
5178 } else if (Tok.getString() == "mips64r2") {
5179 return parseSetFeature(Mips::FeatureMips64r2);
5180 } else if (Tok.getString() == "mips64r3") {
5181 return parseSetFeature(Mips::FeatureMips64r3);
5182 } else if (Tok.getString() == "mips64r5") {
5183 return parseSetFeature(Mips::FeatureMips64r5);
5184 } else if (Tok.getString() == "mips64r6") {
5185 return parseSetFeature(Mips::FeatureMips64r6);
5186 } else if (Tok.getString() == "dsp") {
5187 return parseSetFeature(Mips::FeatureDSP);
5188 } else if (Tok.getString() == "nodsp") {
5189 return parseSetNoDspDirective();
5190 } else if (Tok.getString() == "msa") {
5191 return parseSetMsaDirective();
5192 } else if (Tok.getString() == "nomsa") {
5193 return parseSetNoMsaDirective();
5194 } else if (Tok.getString() == "softfloat") {
5195 return parseSetSoftFloatDirective();
5196 } else if (Tok.getString() == "hardfloat") {
5197 return parseSetHardFloatDirective();
5199 // It is just an identifier, look for an assignment.
5200 parseSetAssignment();
5207 /// parseDataDirective
5208 /// ::= .word [ expression (, expression)* ]
5209 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5210 MCAsmParser &Parser = getParser();
5211 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5213 const MCExpr *Value;
5214 if (getParser().parseExpression(Value))
5217 getParser().getStreamer().EmitValue(Value, Size);
5219 if (getLexer().is(AsmToken::EndOfStatement))
5222 if (getLexer().isNot(AsmToken::Comma))
5223 return Error(L, "unexpected token, expected comma");
5232 /// parseDirectiveGpWord
5233 /// ::= .gpword local_sym
5234 bool MipsAsmParser::parseDirectiveGpWord() {
5235 MCAsmParser &Parser = getParser();
5236 const MCExpr *Value;
5237 // EmitGPRel32Value requires an expression, so we are using base class
5238 // method to evaluate the expression.
5239 if (getParser().parseExpression(Value))
5241 getParser().getStreamer().EmitGPRel32Value(Value);
5243 if (getLexer().isNot(AsmToken::EndOfStatement))
5244 return Error(getLexer().getLoc(),
5245 "unexpected token, expected end of statement");
5246 Parser.Lex(); // Eat EndOfStatement token.
5250 /// parseDirectiveGpDWord
5251 /// ::= .gpdword local_sym
5252 bool MipsAsmParser::parseDirectiveGpDWord() {
5253 MCAsmParser &Parser = getParser();
5254 const MCExpr *Value;
5255 // EmitGPRel64Value requires an expression, so we are using base class
5256 // method to evaluate the expression.
5257 if (getParser().parseExpression(Value))
5259 getParser().getStreamer().EmitGPRel64Value(Value);
5261 if (getLexer().isNot(AsmToken::EndOfStatement))
5262 return Error(getLexer().getLoc(),
5263 "unexpected token, expected end of statement");
5264 Parser.Lex(); // Eat EndOfStatement token.
5268 bool MipsAsmParser::parseDirectiveOption() {
5269 MCAsmParser &Parser = getParser();
5270 // Get the option token.
5271 AsmToken Tok = Parser.getTok();
5272 // At the moment only identifiers are supported.
5273 if (Tok.isNot(AsmToken::Identifier)) {
5274 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5275 Parser.eatToEndOfStatement();
5279 StringRef Option = Tok.getIdentifier();
5281 if (Option == "pic0") {
5282 // MipsAsmParser needs to know if the current PIC mode changes.
5283 IsPicEnabled = false;
5285 getTargetStreamer().emitDirectiveOptionPic0();
5287 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5288 Error(Parser.getTok().getLoc(),
5289 "unexpected token, expected end of statement");
5290 Parser.eatToEndOfStatement();
5295 if (Option == "pic2") {
5296 // MipsAsmParser needs to know if the current PIC mode changes.
5297 IsPicEnabled = true;
5299 getTargetStreamer().emitDirectiveOptionPic2();
5301 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5302 Error(Parser.getTok().getLoc(),
5303 "unexpected token, expected end of statement");
5304 Parser.eatToEndOfStatement();
5310 Warning(Parser.getTok().getLoc(),
5311 "unknown option, expected 'pic0' or 'pic2'");
5312 Parser.eatToEndOfStatement();
5316 /// parseInsnDirective
5318 bool MipsAsmParser::parseInsnDirective() {
5319 // If this is not the end of the statement, report an error.
5320 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5321 reportParseError("unexpected token, expected end of statement");
5325 // The actual label marking happens in
5326 // MipsELFStreamer::createPendingLabelRelocs().
5327 getTargetStreamer().emitDirectiveInsn();
5329 getParser().Lex(); // Eat EndOfStatement token.
5333 /// parseDirectiveModule
5334 /// ::= .module oddspreg
5335 /// ::= .module nooddspreg
5336 /// ::= .module fp=value
5337 /// ::= .module softfloat
5338 /// ::= .module hardfloat
5339 bool MipsAsmParser::parseDirectiveModule() {
5340 MCAsmParser &Parser = getParser();
5341 MCAsmLexer &Lexer = getLexer();
5342 SMLoc L = Lexer.getLoc();
5344 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5345 // TODO : get a better message.
5346 reportParseError(".module directive must appear before any code");
5351 if (Parser.parseIdentifier(Option)) {
5352 reportParseError("expected .module option identifier");
5356 if (Option == "oddspreg") {
5357 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5359 // Synchronize the abiflags information with the FeatureBits information we
5361 getTargetStreamer().updateABIInfo(*this);
5363 // If printing assembly, use the recently updated abiflags information.
5364 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5365 // emitted at the end).
5366 getTargetStreamer().emitDirectiveModuleOddSPReg();
5368 // If this is not the end of the statement, report an error.
5369 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5370 reportParseError("unexpected token, expected end of statement");
5374 return false; // parseDirectiveModule has finished successfully.
5375 } else if (Option == "nooddspreg") {
5377 Error(L, "'.module nooddspreg' requires the O32 ABI");
5381 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5383 // Synchronize the abiflags information with the FeatureBits information we
5385 getTargetStreamer().updateABIInfo(*this);
5387 // If printing assembly, use the recently updated abiflags information.
5388 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5389 // emitted at the end).
5390 getTargetStreamer().emitDirectiveModuleOddSPReg();
5392 // If this is not the end of the statement, report an error.
5393 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5394 reportParseError("unexpected token, expected end of statement");
5398 return false; // parseDirectiveModule has finished successfully.
5399 } else if (Option == "fp") {
5400 return parseDirectiveModuleFP();
5401 } else if (Option == "softfloat") {
5402 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5404 // Synchronize the ABI Flags information with the FeatureBits information we
5406 getTargetStreamer().updateABIInfo(*this);
5408 // If printing assembly, use the recently updated ABI Flags information.
5409 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5411 getTargetStreamer().emitDirectiveModuleSoftFloat();
5413 // If this is not the end of the statement, report an error.
5414 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5415 reportParseError("unexpected token, expected end of statement");
5419 return false; // parseDirectiveModule has finished successfully.
5420 } else if (Option == "hardfloat") {
5421 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5423 // Synchronize the ABI Flags information with the FeatureBits information we
5425 getTargetStreamer().updateABIInfo(*this);
5427 // If printing assembly, use the recently updated ABI Flags information.
5428 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5430 getTargetStreamer().emitDirectiveModuleHardFloat();
5432 // If this is not the end of the statement, report an error.
5433 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5434 reportParseError("unexpected token, expected end of statement");
5438 return false; // parseDirectiveModule has finished successfully.
5440 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5444 /// parseDirectiveModuleFP
5448 bool MipsAsmParser::parseDirectiveModuleFP() {
5449 MCAsmParser &Parser = getParser();
5450 MCAsmLexer &Lexer = getLexer();
5452 if (Lexer.isNot(AsmToken::Equal)) {
5453 reportParseError("unexpected token, expected equals sign '='");
5456 Parser.Lex(); // Eat '=' token.
5458 MipsABIFlagsSection::FpABIKind FpABI;
5459 if (!parseFpABIValue(FpABI, ".module"))
5462 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5463 reportParseError("unexpected token, expected end of statement");
5467 // Synchronize the abiflags information with the FeatureBits information we
5469 getTargetStreamer().updateABIInfo(*this);
5471 // If printing assembly, use the recently updated abiflags information.
5472 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5473 // emitted at the end).
5474 getTargetStreamer().emitDirectiveModuleFP();
5476 Parser.Lex(); // Consume the EndOfStatement.
5480 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5481 StringRef Directive) {
5482 MCAsmParser &Parser = getParser();
5483 MCAsmLexer &Lexer = getLexer();
5484 bool ModuleLevelOptions = Directive == ".module";
5486 if (Lexer.is(AsmToken::Identifier)) {
5487 StringRef Value = Parser.getTok().getString();
5490 if (Value != "xx") {
5491 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5496 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5500 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5501 if (ModuleLevelOptions) {
5502 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5503 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5505 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5506 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5511 if (Lexer.is(AsmToken::Integer)) {
5512 unsigned Value = Parser.getTok().getIntVal();
5515 if (Value != 32 && Value != 64) {
5516 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5522 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5526 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5527 if (ModuleLevelOptions) {
5528 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5529 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5531 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5532 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5535 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5536 if (ModuleLevelOptions) {
5537 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5538 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5540 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5541 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5551 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5552 MCAsmParser &Parser = getParser();
5553 StringRef IDVal = DirectiveID.getString();
5555 if (IDVal == ".cpload")
5556 return parseDirectiveCpLoad(DirectiveID.getLoc());
5557 if (IDVal == ".cprestore")
5558 return parseDirectiveCpRestore(DirectiveID.getLoc());
5559 if (IDVal == ".dword") {
5560 parseDataDirective(8, DirectiveID.getLoc());
5563 if (IDVal == ".ent") {
5564 StringRef SymbolName;
5566 if (Parser.parseIdentifier(SymbolName)) {
5567 reportParseError("expected identifier after .ent");
5571 // There's an undocumented extension that allows an integer to
5572 // follow the name of the procedure which AFAICS is ignored by GAS.
5573 // Example: .ent foo,2
5574 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5575 if (getLexer().isNot(AsmToken::Comma)) {
5576 // Even though we accept this undocumented extension for compatibility
5577 // reasons, the additional integer argument does not actually change
5578 // the behaviour of the '.ent' directive, so we would like to discourage
5579 // its use. We do this by not referring to the extended version in
5580 // error messages which are not directly related to its use.
5581 reportParseError("unexpected token, expected end of statement");
5584 Parser.Lex(); // Eat the comma.
5585 const MCExpr *DummyNumber;
5586 int64_t DummyNumberVal;
5587 // If the user was explicitly trying to use the extended version,
5588 // we still give helpful extension-related error messages.
5589 if (Parser.parseExpression(DummyNumber)) {
5590 reportParseError("expected number after comma");
5593 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5594 reportParseError("expected an absolute expression after comma");
5599 // If this is not the end of the statement, report an error.
5600 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5601 reportParseError("unexpected token, expected end of statement");
5605 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5607 getTargetStreamer().emitDirectiveEnt(*Sym);
5609 IsCpRestoreSet = false;
5613 if (IDVal == ".end") {
5614 StringRef SymbolName;
5616 if (Parser.parseIdentifier(SymbolName)) {
5617 reportParseError("expected identifier after .end");
5621 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5622 reportParseError("unexpected token, expected end of statement");
5626 if (CurrentFn == nullptr) {
5627 reportParseError(".end used without .ent");
5631 if ((SymbolName != CurrentFn->getName())) {
5632 reportParseError(".end symbol does not match .ent symbol");
5636 getTargetStreamer().emitDirectiveEnd(SymbolName);
5637 CurrentFn = nullptr;
5638 IsCpRestoreSet = false;
5642 if (IDVal == ".frame") {
5643 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5644 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5645 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5646 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5647 reportParseError("expected stack register");
5651 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5652 if (!StackRegOpnd.isGPRAsmReg()) {
5653 reportParseError(StackRegOpnd.getStartLoc(),
5654 "expected general purpose register");
5657 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5659 if (Parser.getTok().is(AsmToken::Comma))
5662 reportParseError("unexpected token, expected comma");
5666 // Parse the frame size.
5667 const MCExpr *FrameSize;
5668 int64_t FrameSizeVal;
5670 if (Parser.parseExpression(FrameSize)) {
5671 reportParseError("expected frame size value");
5675 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5676 reportParseError("frame size not an absolute expression");
5680 if (Parser.getTok().is(AsmToken::Comma))
5683 reportParseError("unexpected token, expected comma");
5687 // Parse the return register.
5689 ResTy = parseAnyRegister(TmpReg);
5690 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5691 reportParseError("expected return register");
5695 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5696 if (!ReturnRegOpnd.isGPRAsmReg()) {
5697 reportParseError(ReturnRegOpnd.getStartLoc(),
5698 "expected general purpose register");
5702 // If this is not the end of the statement, report an error.
5703 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5704 reportParseError("unexpected token, expected end of statement");
5708 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5709 ReturnRegOpnd.getGPR32Reg());
5710 IsCpRestoreSet = false;
5714 if (IDVal == ".set") {
5715 return parseDirectiveSet();
5718 if (IDVal == ".mask" || IDVal == ".fmask") {
5719 // .mask bitmask, frame_offset
5720 // bitmask: One bit for each register used.
5721 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5722 // first register is expected to be saved.
5724 // .mask 0x80000000, -4
5725 // .fmask 0x80000000, -4
5728 // Parse the bitmask
5729 const MCExpr *BitMask;
5732 if (Parser.parseExpression(BitMask)) {
5733 reportParseError("expected bitmask value");
5737 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5738 reportParseError("bitmask not an absolute expression");
5742 if (Parser.getTok().is(AsmToken::Comma))
5745 reportParseError("unexpected token, expected comma");
5749 // Parse the frame_offset
5750 const MCExpr *FrameOffset;
5751 int64_t FrameOffsetVal;
5753 if (Parser.parseExpression(FrameOffset)) {
5754 reportParseError("expected frame offset value");
5758 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5759 reportParseError("frame offset not an absolute expression");
5763 // If this is not the end of the statement, report an error.
5764 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5765 reportParseError("unexpected token, expected end of statement");
5769 if (IDVal == ".mask")
5770 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5772 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5776 if (IDVal == ".nan")
5777 return parseDirectiveNaN();
5779 if (IDVal == ".gpword") {
5780 parseDirectiveGpWord();
5784 if (IDVal == ".gpdword") {
5785 parseDirectiveGpDWord();
5789 if (IDVal == ".word") {
5790 parseDataDirective(4, DirectiveID.getLoc());
5794 if (IDVal == ".option")
5795 return parseDirectiveOption();
5797 if (IDVal == ".abicalls") {
5798 getTargetStreamer().emitDirectiveAbiCalls();
5799 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5800 Error(Parser.getTok().getLoc(),
5801 "unexpected token, expected end of statement");
5803 Parser.eatToEndOfStatement();
5808 if (IDVal == ".cpsetup")
5809 return parseDirectiveCPSetup();
5811 if (IDVal == ".cpreturn")
5812 return parseDirectiveCPReturn();
5814 if (IDVal == ".module")
5815 return parseDirectiveModule();
5817 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5818 return parseInternalDirectiveReallowModule();
5820 if (IDVal == ".insn")
5821 return parseInsnDirective();
5826 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5827 // If this is not the end of the statement, report an error.
5828 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5829 reportParseError("unexpected token, expected end of statement");
5833 getTargetStreamer().reallowModuleDirective();
5835 getParser().Lex(); // Eat EndOfStatement token.
5839 extern "C" void LLVMInitializeMipsAsmParser() {
5840 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5841 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5842 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5843 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5846 #define GET_REGISTER_MATCHER
5847 #define GET_MATCHER_IMPLEMENTATION
5848 #include "MipsGenAsmMatcher.inc"