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 // FIXME: The way we're handling symbols right now prevents simple expressions
2345 // like foo+8. We'll be able to fix this once our unary operators (%hi
2346 // and similar) are treated as operators rather than as fixup types.
2347 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2348 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2349 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2350 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2351 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2353 bool UseSrcReg = SrcReg != Mips::NoRegister;
2355 // This is the 64-bit symbol address expansion.
2356 if (ABI.ArePtrs64bit() && isGP64bit()) {
2357 // We always need AT for the 64-bit expansion.
2358 // If it is not available we exit.
2359 unsigned ATReg = getATReg(IDLoc);
2363 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2364 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2365 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2366 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2368 if (UseSrcReg && (DstReg == SrcReg)) {
2369 // If $rs is the same as $rd:
2370 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2371 // daddiu $at, $at, %higher(sym)
2372 // dsll $at, $at, 16
2373 // daddiu $at, $at, %hi(sym)
2374 // dsll $at, $at, 16
2375 // daddiu $at, $at, %lo(sym)
2376 // daddu $rd, $at, $rd
2377 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2379 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2380 IDLoc, Instructions);
2381 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2382 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2384 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2385 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2387 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2392 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2393 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2394 // lui $at, %hi(sym)
2395 // daddiu $rd, $rd, %higher(sym)
2396 // daddiu $at, $at, %lo(sym)
2397 // dsll32 $rd, $rd, 0
2398 // daddu $rd, $rd, $at
2399 // (daddu $rd, $rd, $rs)
2400 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2402 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2404 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2405 IDLoc, Instructions);
2406 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2408 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2409 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2411 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2416 // And now, the 32-bit symbol address expansion:
2417 // If $rs is the same as $rd:
2418 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2419 // ori $at, $at, %lo(sym)
2420 // addu $rd, $at, $rd
2421 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2422 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2423 // ori $rd, $rd, %lo(sym)
2424 // (addu $rd, $rd, $rs)
2425 unsigned TmpReg = DstReg;
2426 if (UseSrcReg && (DstReg == SrcReg)) {
2427 // If $rs is the same as $rd, we need to use AT.
2428 // If it is not available we exit.
2429 unsigned ATReg = getATReg(IDLoc);
2435 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2436 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2440 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2442 assert(DstReg == TmpReg);
2447 bool MipsAsmParser::expandUncondBranchMMPseudo(
2448 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2449 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2450 "unexpected number of operands");
2452 MCOperand Offset = Inst.getOperand(0);
2453 if (Offset.isExpr()) {
2455 Inst.setOpcode(Mips::BEQ_MM);
2456 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2457 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2458 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2460 assert(Offset.isImm() && "expected immediate operand kind");
2461 if (isIntN(11, Offset.getImm())) {
2462 // If offset fits into 11 bits then this instruction becomes microMIPS
2463 // 16-bit unconditional branch instruction.
2464 if (inMicroMipsMode())
2465 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2467 if (!isIntN(17, Offset.getImm()))
2468 Error(IDLoc, "branch target out of range");
2469 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2470 Error(IDLoc, "branch to misaligned address");
2472 Inst.setOpcode(Mips::BEQ_MM);
2473 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2474 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2475 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2478 Instructions.push_back(Inst);
2480 // If .set reorder is active and branch instruction has a delay slot,
2481 // emit a NOP after it.
2482 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2483 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2484 createNop(true, IDLoc, Instructions);
2489 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2490 SmallVectorImpl<MCInst> &Instructions) {
2491 const MCOperand &DstRegOp = Inst.getOperand(0);
2492 assert(DstRegOp.isReg() && "expected register operand kind");
2494 const MCOperand &ImmOp = Inst.getOperand(1);
2495 assert(ImmOp.isImm() && "expected immediate operand kind");
2497 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2498 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2500 unsigned OpCode = 0;
2501 switch(Inst.getOpcode()) {
2509 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2513 int64_t ImmValue = ImmOp.getImm();
2514 if (ImmValue == 0) {
2516 BranchInst.setOpcode(OpCode);
2517 BranchInst.addOperand(DstRegOp);
2518 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2519 BranchInst.addOperand(MemOffsetOp);
2520 Instructions.push_back(BranchInst);
2522 warnIfNoMacro(IDLoc);
2524 unsigned ATReg = getATReg(IDLoc);
2528 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2529 IDLoc, Instructions))
2533 BranchInst.setOpcode(OpCode);
2534 BranchInst.addOperand(DstRegOp);
2535 BranchInst.addOperand(MCOperand::createReg(ATReg));
2536 BranchInst.addOperand(MemOffsetOp);
2537 Instructions.push_back(BranchInst);
2542 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2543 SmallVectorImpl<MCInst> &Instructions,
2544 bool isLoad, bool isImmOpnd) {
2546 unsigned ImmOffset, HiOffset, LoOffset;
2547 const MCExpr *ExprOffset;
2549 // 1st operand is either the source or destination register.
2550 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2551 unsigned RegOpNum = Inst.getOperand(0).getReg();
2552 // 2nd operand is the base register.
2553 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2554 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2555 // 3rd operand is either an immediate or expression.
2557 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2558 ImmOffset = Inst.getOperand(2).getImm();
2559 LoOffset = ImmOffset & 0x0000ffff;
2560 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2561 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2562 if (LoOffset & 0x8000)
2565 ExprOffset = Inst.getOperand(2).getExpr();
2566 // All instructions will have the same location.
2567 TempInst.setLoc(IDLoc);
2568 // These are some of the types of expansions we perform here:
2569 // 1) lw $8, sym => lui $8, %hi(sym)
2570 // lw $8, %lo(sym)($8)
2571 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2573 // lw $8, %lo(offset)($9)
2574 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2576 // lw $8, %lo(offset)($at)
2577 // 4) sw $8, sym => lui $at, %hi(sym)
2578 // sw $8, %lo(sym)($at)
2579 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2581 // sw $8, %lo(offset)($at)
2582 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2583 // ldc1 $f0, %lo(sym)($at)
2585 // For load instructions we can use the destination register as a temporary
2586 // if base and dst are different (examples 1 and 2) and if the base register
2587 // is general purpose otherwise we must use $at (example 6) and error if it's
2588 // not available. For stores we must use $at (examples 4 and 5) because we
2589 // must not clobber the source register setting up the offset.
2590 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2591 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2592 unsigned RegClassIDOp0 =
2593 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2594 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2595 (RegClassIDOp0 == Mips::GPR64RegClassID);
2596 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2597 TmpRegNum = RegOpNum;
2599 // At this point we need AT to perform the expansions and we exit if it is
2601 TmpRegNum = getATReg(IDLoc);
2606 TempInst.setOpcode(Mips::LUi);
2607 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2609 TempInst.addOperand(MCOperand::createImm(HiOffset));
2611 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2612 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2614 // Add the instruction to the list.
2615 Instructions.push_back(TempInst);
2616 // Prepare TempInst for next instruction.
2618 // Add temp register to base.
2619 if (BaseRegNum != Mips::ZERO) {
2620 TempInst.setOpcode(Mips::ADDu);
2621 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2622 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2623 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2624 Instructions.push_back(TempInst);
2627 // And finally, create original instruction with low part
2628 // of offset and new base.
2629 TempInst.setOpcode(Inst.getOpcode());
2630 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2631 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2633 TempInst.addOperand(MCOperand::createImm(LoOffset));
2635 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2636 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2638 Instructions.push_back(TempInst);
2643 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2644 SmallVectorImpl<MCInst> &Instructions) {
2645 unsigned OpNum = Inst.getNumOperands();
2646 unsigned Opcode = Inst.getOpcode();
2647 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2649 assert (Inst.getOperand(OpNum - 1).isImm() &&
2650 Inst.getOperand(OpNum - 2).isReg() &&
2651 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2653 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2654 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2655 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2656 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2657 // It can be implemented as SWM16 or LWM16 instruction.
2658 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2660 Inst.setOpcode(NewOpcode);
2661 Instructions.push_back(Inst);
2665 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2666 SmallVectorImpl<MCInst> &Instructions) {
2667 unsigned PseudoOpcode = Inst.getOpcode();
2668 unsigned SrcReg = Inst.getOperand(0).getReg();
2669 unsigned TrgReg = Inst.getOperand(1).getReg();
2670 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2672 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2673 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2675 switch (PseudoOpcode) {
2680 AcceptsEquality = false;
2681 ReverseOrderSLT = false;
2682 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2683 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2684 ZeroSrcOpcode = Mips::BGTZ;
2685 ZeroTrgOpcode = Mips::BLTZ;
2691 AcceptsEquality = true;
2692 ReverseOrderSLT = true;
2693 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2694 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2695 ZeroSrcOpcode = Mips::BGEZ;
2696 ZeroTrgOpcode = Mips::BLEZ;
2702 AcceptsEquality = true;
2703 ReverseOrderSLT = false;
2704 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2705 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2706 ZeroSrcOpcode = Mips::BLEZ;
2707 ZeroTrgOpcode = Mips::BGEZ;
2713 AcceptsEquality = false;
2714 ReverseOrderSLT = true;
2715 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2716 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2717 ZeroSrcOpcode = Mips::BLTZ;
2718 ZeroTrgOpcode = Mips::BGTZ;
2721 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2725 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2726 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2727 if (IsSrcRegZero && IsTrgRegZero) {
2728 // FIXME: All of these Opcode-specific if's are needed for compatibility
2729 // with GAS' behaviour. However, they may not generate the most efficient
2730 // code in some circumstances.
2731 if (PseudoOpcode == Mips::BLT) {
2732 BranchInst.setOpcode(Mips::BLTZ);
2733 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2734 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2735 Instructions.push_back(BranchInst);
2738 if (PseudoOpcode == Mips::BLE) {
2739 BranchInst.setOpcode(Mips::BLEZ);
2740 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2741 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2742 Instructions.push_back(BranchInst);
2743 Warning(IDLoc, "branch is always taken");
2746 if (PseudoOpcode == Mips::BGE) {
2747 BranchInst.setOpcode(Mips::BGEZ);
2748 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2749 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2750 Instructions.push_back(BranchInst);
2751 Warning(IDLoc, "branch is always taken");
2754 if (PseudoOpcode == Mips::BGT) {
2755 BranchInst.setOpcode(Mips::BGTZ);
2756 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2757 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2758 Instructions.push_back(BranchInst);
2761 if (PseudoOpcode == Mips::BGTU) {
2762 BranchInst.setOpcode(Mips::BNE);
2763 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2764 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2765 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2766 Instructions.push_back(BranchInst);
2769 if (AcceptsEquality) {
2770 // If both registers are $0 and the pseudo-branch accepts equality, it
2771 // will always be taken, so we emit an unconditional branch.
2772 BranchInst.setOpcode(Mips::BEQ);
2773 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2774 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2775 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2776 Instructions.push_back(BranchInst);
2777 Warning(IDLoc, "branch is always taken");
2780 // If both registers are $0 and the pseudo-branch does not accept
2781 // equality, it will never be taken, so we don't have to emit anything.
2784 if (IsSrcRegZero || IsTrgRegZero) {
2785 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2786 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2787 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2788 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2789 // the pseudo-branch will never be taken, so we don't emit anything.
2790 // This only applies to unsigned pseudo-branches.
2793 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2794 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2795 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2796 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2797 // the pseudo-branch will always be taken, so we emit an unconditional
2799 // This only applies to unsigned pseudo-branches.
2800 BranchInst.setOpcode(Mips::BEQ);
2801 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2802 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2803 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2804 Instructions.push_back(BranchInst);
2805 Warning(IDLoc, "branch is always taken");
2809 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2810 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2811 // the pseudo-branch will be taken only when the non-zero register is
2812 // different from 0, so we emit a BNEZ.
2814 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2815 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2816 // the pseudo-branch will be taken only when the non-zero register is
2817 // equal to 0, so we emit a BEQZ.
2819 // Because only BLEU and BGEU branch on equality, we can use the
2820 // AcceptsEquality variable to decide when to emit the BEQZ.
2821 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2822 BranchInst.addOperand(
2823 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2824 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2825 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2826 Instructions.push_back(BranchInst);
2829 // If we have a signed pseudo-branch and one of the registers is $0,
2830 // we can use an appropriate compare-to-zero branch. We select which one
2831 // to use in the switch statement above.
2832 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2833 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2834 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2835 Instructions.push_back(BranchInst);
2839 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2840 // expansions. If it is not available, we return.
2841 unsigned ATRegNum = getATReg(IDLoc);
2845 warnIfNoMacro(IDLoc);
2847 // SLT fits well with 2 of our 4 pseudo-branches:
2848 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2849 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2850 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2851 // This is accomplished by using a BNEZ with the result of the SLT.
2853 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2854 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2855 // Because only BGE and BLE branch on equality, we can use the
2856 // AcceptsEquality variable to decide when to emit the BEQZ.
2857 // Note that the order of the SLT arguments doesn't change between
2860 // The same applies to the unsigned variants, except that SLTu is used
2863 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2864 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2865 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2866 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2867 Instructions.push_back(SetInst);
2870 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2872 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQL : Mips::BNEL);
2873 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2874 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2875 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2876 Instructions.push_back(BranchInst);
2880 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2881 SmallVectorImpl<MCInst> &Instructions,
2882 const bool IsMips64, const bool Signed) {
2883 if (hasMips32r6()) {
2884 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2888 warnIfNoMacro(IDLoc);
2890 const MCOperand &RsRegOp = Inst.getOperand(0);
2891 assert(RsRegOp.isReg() && "expected register operand kind");
2892 unsigned RsReg = RsRegOp.getReg();
2894 const MCOperand &RtRegOp = Inst.getOperand(1);
2895 assert(RtRegOp.isReg() && "expected register operand kind");
2896 unsigned RtReg = RtRegOp.getReg();
2901 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2902 ZeroReg = Mips::ZERO_64;
2904 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2905 ZeroReg = Mips::ZERO;
2908 bool UseTraps = useTraps();
2910 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2911 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2912 Warning(IDLoc, "dividing zero by zero");
2914 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2916 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2920 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2924 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2929 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2930 Warning(IDLoc, "division by zero");
2933 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2937 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2942 // FIXME: The values for these two BranchTarget variables may be different in
2943 // micromips. These magic numbers need to be removed.
2944 unsigned BranchTargetNoTraps;
2945 unsigned BranchTarget;
2948 BranchTarget = IsMips64 ? 12 : 8;
2949 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2951 BranchTarget = IsMips64 ? 20 : 16;
2952 BranchTargetNoTraps = 8;
2953 // Branch to the li instruction.
2954 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2958 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2961 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2964 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2968 unsigned ATReg = getATReg(IDLoc);
2972 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2974 // Branch to the mflo instruction.
2975 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2976 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2977 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2979 // Branch to the mflo instruction.
2980 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2981 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2985 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2987 // Branch to the mflo instruction.
2988 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2989 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2990 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2992 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2996 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2997 SmallVectorImpl<MCInst> &Instructions) {
2998 if (hasMips32r6() || hasMips64r6()) {
2999 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3003 warnIfNoMacro(IDLoc);
3005 const MCOperand &DstRegOp = Inst.getOperand(0);
3006 assert(DstRegOp.isReg() && "expected register operand kind");
3008 const MCOperand &SrcRegOp = Inst.getOperand(1);
3009 assert(SrcRegOp.isReg() && "expected register operand kind");
3011 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3012 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3014 unsigned DstReg = DstRegOp.getReg();
3015 unsigned SrcReg = SrcRegOp.getReg();
3016 int64_t OffsetValue = OffsetImmOp.getImm();
3018 // NOTE: We always need AT for ULHU, as it is always used as the source
3019 // register for one of the LBu's.
3020 unsigned ATReg = getATReg(IDLoc);
3024 // When the value of offset+1 does not fit in 16 bits, we have to load the
3025 // offset in AT, (D)ADDu the original source register (if there was one), and
3026 // then use AT as the source register for the 2 generated LBu's.
3027 bool LoadedOffsetInAT = false;
3028 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3029 LoadedOffsetInAT = true;
3031 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3032 true, IDLoc, Instructions))
3035 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3036 // because it will make our output more similar to GAS'. For example,
3037 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3038 // instead of just an "ori $1, $9, 32768".
3039 // NOTE: If there is no source register specified in the ULHU, the parser
3040 // will interpret it as $0.
3041 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3042 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3045 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3046 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3047 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3049 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3051 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3052 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3054 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3055 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3058 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3061 TmpInst.setOpcode(Mips::LBu);
3062 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
3063 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
3064 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
3065 Instructions.push_back(TmpInst);
3068 TmpInst.setOpcode(Mips::LBu);
3069 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
3070 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
3071 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
3072 Instructions.push_back(TmpInst);
3075 TmpInst.setOpcode(Mips::SLL);
3076 TmpInst.addOperand(MCOperand::createReg(SllReg));
3077 TmpInst.addOperand(MCOperand::createReg(SllReg));
3078 TmpInst.addOperand(MCOperand::createImm(8));
3079 Instructions.push_back(TmpInst);
3082 TmpInst.setOpcode(Mips::OR);
3083 TmpInst.addOperand(MCOperand::createReg(DstReg));
3084 TmpInst.addOperand(MCOperand::createReg(DstReg));
3085 TmpInst.addOperand(MCOperand::createReg(ATReg));
3086 Instructions.push_back(TmpInst);
3091 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3092 SmallVectorImpl<MCInst> &Instructions) {
3093 if (hasMips32r6() || hasMips64r6()) {
3094 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3098 const MCOperand &DstRegOp = Inst.getOperand(0);
3099 assert(DstRegOp.isReg() && "expected register operand kind");
3101 const MCOperand &SrcRegOp = Inst.getOperand(1);
3102 assert(SrcRegOp.isReg() && "expected register operand kind");
3104 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3105 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3107 unsigned SrcReg = SrcRegOp.getReg();
3108 int64_t OffsetValue = OffsetImmOp.getImm();
3111 // When the value of offset+3 does not fit in 16 bits, we have to load the
3112 // offset in AT, (D)ADDu the original source register (if there was one), and
3113 // then use AT as the source register for the generated LWL and LWR.
3114 bool LoadedOffsetInAT = false;
3115 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3116 ATReg = getATReg(IDLoc);
3119 LoadedOffsetInAT = true;
3121 warnIfNoMacro(IDLoc);
3123 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3124 true, IDLoc, Instructions))
3127 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3128 // because it will make our output more similar to GAS'. For example,
3129 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3130 // instead of just an "ori $1, $9, 32768".
3131 // NOTE: If there is no source register specified in the ULW, the parser
3132 // will interpret it as $0.
3133 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3134 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3137 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3138 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3140 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3141 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3143 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3144 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3147 MCInst LeftLoadInst;
3148 LeftLoadInst.setOpcode(Mips::LWL);
3149 LeftLoadInst.addOperand(DstRegOp);
3150 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3151 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3152 Instructions.push_back(LeftLoadInst);
3154 MCInst RightLoadInst;
3155 RightLoadInst.setOpcode(Mips::LWR);
3156 RightLoadInst.addOperand(DstRegOp);
3157 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3158 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3159 Instructions.push_back(RightLoadInst);
3164 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3165 SmallVectorImpl<MCInst> &Instructions) {
3167 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3168 assert (Inst.getOperand(0).isReg() &&
3169 Inst.getOperand(1).isReg() &&
3170 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3172 unsigned ATReg = Mips::NoRegister;
3173 unsigned FinalDstReg = Mips::NoRegister;
3174 unsigned DstReg = Inst.getOperand(0).getReg();
3175 unsigned SrcReg = Inst.getOperand(1).getReg();
3176 int64_t ImmValue = Inst.getOperand(2).getImm();
3178 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3180 unsigned FinalOpcode = Inst.getOpcode();
3182 if (DstReg == SrcReg) {
3183 ATReg = getATReg(Inst.getLoc());
3186 FinalDstReg = DstReg;
3190 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3191 switch (FinalOpcode) {
3193 llvm_unreachable("unimplemented expansion");
3195 FinalOpcode = Mips::ADD;
3198 FinalOpcode = Mips::ADDu;
3201 FinalOpcode = Mips::AND;
3203 case (Mips::NORImm):
3204 FinalOpcode = Mips::NOR;
3207 FinalOpcode = Mips::OR;
3210 FinalOpcode = Mips::SLT;
3213 FinalOpcode = Mips::SLTu;
3216 FinalOpcode = Mips::XOR;
3223 tmpInst.setLoc(Inst.getLoc());
3224 tmpInst.setOpcode(FinalOpcode);
3225 if (FinalDstReg == Mips::NoRegister) {
3226 tmpInst.addOperand(MCOperand::createReg(DstReg));
3227 tmpInst.addOperand(MCOperand::createReg(DstReg));
3228 tmpInst.addOperand(MCOperand::createReg(SrcReg));
3230 tmpInst.addOperand(MCOperand::createReg(FinalDstReg));
3231 tmpInst.addOperand(MCOperand::createReg(FinalDstReg));
3232 tmpInst.addOperand(MCOperand::createReg(DstReg));
3234 Instructions.push_back(tmpInst);
3240 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3241 SmallVectorImpl<MCInst> &Instructions) {
3243 if (hasShortDelaySlot) {
3244 NopInst.setOpcode(Mips::MOVE16_MM);
3245 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3246 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3248 NopInst.setOpcode(Mips::SLL);
3249 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3250 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3251 NopInst.addOperand(MCOperand::createImm(0));
3253 Instructions.push_back(NopInst);
3256 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3257 unsigned TrgReg, bool Is64Bit,
3258 SmallVectorImpl<MCInst> &Instructions) {
3259 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3263 void MipsAsmParser::createCpRestoreMemOp(
3264 bool IsLoad, int StackOffset, SMLoc IDLoc,
3265 SmallVectorImpl<MCInst> &Instructions) {
3267 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3268 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3269 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3270 MemInst.addOperand(MCOperand::createImm(StackOffset));
3272 // If the offset can not fit into 16 bits, we need to expand.
3273 if (!isInt<16>(StackOffset))
3274 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3276 Instructions.push_back(MemInst);
3279 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3280 // As described by the Mips32r2 spec, the registers Rd and Rs for
3281 // jalr.hb must be different.
3282 unsigned Opcode = Inst.getOpcode();
3284 if (Opcode == Mips::JALR_HB &&
3285 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3286 return Match_RequiresDifferentSrcAndDst;
3288 return Match_Success;
3291 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3292 OperandVector &Operands,
3294 uint64_t &ErrorInfo,
3295 bool MatchingInlineAsm) {
3298 SmallVector<MCInst, 8> Instructions;
3299 unsigned MatchResult =
3300 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3302 switch (MatchResult) {
3303 case Match_Success: {
3304 if (processInstruction(Inst, IDLoc, Instructions))
3306 for (unsigned i = 0; i < Instructions.size(); i++)
3307 Out.EmitInstruction(Instructions[i], STI);
3310 case Match_MissingFeature:
3311 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3313 case Match_InvalidOperand: {
3314 SMLoc ErrorLoc = IDLoc;
3315 if (ErrorInfo != ~0ULL) {
3316 if (ErrorInfo >= Operands.size())
3317 return Error(IDLoc, "too few operands for instruction");
3319 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3320 if (ErrorLoc == SMLoc())
3324 return Error(ErrorLoc, "invalid operand for instruction");
3326 case Match_MnemonicFail:
3327 return Error(IDLoc, "invalid instruction");
3328 case Match_RequiresDifferentSrcAndDst:
3329 return Error(IDLoc, "source and destination must be different");
3332 llvm_unreachable("Implement any new match types added!");
3335 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3336 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3337 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3338 ") without \".set noat\"");
3341 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3342 if (!AssemblerOptions.back()->isMacro())
3343 Warning(Loc, "macro instruction expanded into multiple instructions");
3347 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3348 SMRange Range, bool ShowColors) {
3349 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3350 Range, SMFixIt(Range, FixMsg),
3354 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3357 CC = StringSwitch<unsigned>(Name)
3393 if (!(isABI_N32() || isABI_N64()))
3396 if (12 <= CC && CC <= 15) {
3397 // Name is one of t4-t7
3398 AsmToken RegTok = getLexer().peekTok();
3399 SMRange RegRange = RegTok.getLocRange();
3401 StringRef FixedName = StringSwitch<StringRef>(Name)
3407 assert(FixedName != "" && "Register name is not one of t4-t7.");
3409 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3410 "Did you mean $" + FixedName + "?", RegRange);
3413 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3414 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3415 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3416 if (8 <= CC && CC <= 11)
3420 CC = StringSwitch<unsigned>(Name)
3432 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3435 CC = StringSwitch<unsigned>(Name)
3436 .Case("hwr_cpunum", 0)
3437 .Case("hwr_synci_step", 1)
3439 .Case("hwr_ccres", 3)
3440 .Case("hwr_ulr", 29)
3446 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3448 if (Name[0] == 'f') {
3449 StringRef NumString = Name.substr(1);
3451 if (NumString.getAsInteger(10, IntVal))
3452 return -1; // This is not an integer.
3453 if (IntVal > 31) // Maximum index for fpu register.
3460 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3462 if (Name.startswith("fcc")) {
3463 StringRef NumString = Name.substr(3);
3465 if (NumString.getAsInteger(10, IntVal))
3466 return -1; // This is not an integer.
3467 if (IntVal > 7) // There are only 8 fcc registers.
3474 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3476 if (Name.startswith("ac")) {
3477 StringRef NumString = Name.substr(2);
3479 if (NumString.getAsInteger(10, IntVal))
3480 return -1; // This is not an integer.
3481 if (IntVal > 3) // There are only 3 acc registers.
3488 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3491 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3500 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3503 CC = StringSwitch<unsigned>(Name)
3506 .Case("msaaccess", 2)
3508 .Case("msamodify", 4)
3509 .Case("msarequest", 5)
3511 .Case("msaunmap", 7)
3517 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3518 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3520 reportParseError(Loc,
3521 "pseudo-instruction requires $at, which is not available");
3524 unsigned AT = getReg(
3525 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3529 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3530 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3533 unsigned MipsAsmParser::getGPR(int RegNo) {
3534 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3538 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3540 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3543 return getReg(RegClass, RegNum);
3546 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3547 MCAsmParser &Parser = getParser();
3548 DEBUG(dbgs() << "parseOperand\n");
3550 // Check if the current operand has a custom associated parser, if so, try to
3551 // custom parse the operand, or fallback to the general approach.
3552 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3553 if (ResTy == MatchOperand_Success)
3555 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3556 // there was a match, but an error occurred, in which case, just return that
3557 // the operand parsing failed.
3558 if (ResTy == MatchOperand_ParseFail)
3561 DEBUG(dbgs() << ".. Generic Parser\n");
3563 switch (getLexer().getKind()) {
3565 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3567 case AsmToken::Dollar: {
3568 // Parse the register.
3569 SMLoc S = Parser.getTok().getLoc();
3571 // Almost all registers have been parsed by custom parsers. There is only
3572 // one exception to this. $zero (and it's alias $0) will reach this point
3573 // for div, divu, and similar instructions because it is not an operand
3574 // to the instruction definition but an explicit register. Special case
3575 // this situation for now.
3576 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3579 // Maybe it is a symbol reference.
3580 StringRef Identifier;
3581 if (Parser.parseIdentifier(Identifier))
3584 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3585 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3586 // Otherwise create a symbol reference.
3588 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3590 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3593 // Else drop to expression parsing.
3594 case AsmToken::LParen:
3595 case AsmToken::Minus:
3596 case AsmToken::Plus:
3597 case AsmToken::Integer:
3598 case AsmToken::Tilde:
3599 case AsmToken::String: {
3600 DEBUG(dbgs() << ".. generic integer\n");
3601 OperandMatchResultTy ResTy = parseImm(Operands);
3602 return ResTy != MatchOperand_Success;
3604 case AsmToken::Percent: {
3605 // It is a symbol reference or constant expression.
3606 const MCExpr *IdVal;
3607 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3608 if (parseRelocOperand(IdVal))
3611 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3613 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3615 } // case AsmToken::Percent
3616 } // switch(getLexer().getKind())
3620 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3621 StringRef RelocStr) {
3623 // Check the type of the expression.
3624 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3625 // It's a constant, evaluate reloc value.
3627 switch (getVariantKind(RelocStr)) {
3628 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3629 // Get the 1st 16-bits.
3630 Val = MCE->getValue() & 0xffff;
3632 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3633 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3634 // 16 bits being negative.
3635 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3637 case MCSymbolRefExpr::VK_Mips_HIGHER:
3638 // Get the 3rd 16-bits.
3639 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3641 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3642 // Get the 4th 16-bits.
3643 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3646 report_fatal_error("unsupported reloc value");
3648 return MCConstantExpr::create(Val, getContext());
3651 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3652 // It's a symbol, create a symbolic expression from the symbol.
3653 const MCSymbol *Symbol = &MSRE->getSymbol();
3654 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3655 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3659 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3660 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3662 // Try to create target expression.
3663 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3664 return MipsMCExpr::create(VK, Expr, getContext());
3666 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3667 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3668 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3672 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3673 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3674 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3677 // Just return the original expression.
3681 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3683 switch (Expr->getKind()) {
3684 case MCExpr::Constant:
3686 case MCExpr::SymbolRef:
3687 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3688 case MCExpr::Binary:
3689 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3690 if (!isEvaluated(BE->getLHS()))
3692 return isEvaluated(BE->getRHS());
3695 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3696 case MCExpr::Target:
3702 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3703 MCAsmParser &Parser = getParser();
3704 Parser.Lex(); // Eat the % token.
3705 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3706 if (Tok.isNot(AsmToken::Identifier))
3709 std::string Str = Tok.getIdentifier();
3711 Parser.Lex(); // Eat the identifier.
3712 // Now make an expression from the rest of the operand.
3713 const MCExpr *IdVal;
3716 if (getLexer().getKind() == AsmToken::LParen) {
3718 Parser.Lex(); // Eat the '(' token.
3719 if (getLexer().getKind() == AsmToken::Percent) {
3720 Parser.Lex(); // Eat the % token.
3721 const AsmToken &nextTok = Parser.getTok();
3722 if (nextTok.isNot(AsmToken::Identifier))
3725 Str += nextTok.getIdentifier();
3726 Parser.Lex(); // Eat the identifier.
3727 if (getLexer().getKind() != AsmToken::LParen)
3732 if (getParser().parseParenExpression(IdVal, EndLoc))
3735 while (getLexer().getKind() == AsmToken::RParen)
3736 Parser.Lex(); // Eat the ')' token.
3739 return true; // Parenthesis must follow the relocation operand.
3741 Res = evaluateRelocExpr(IdVal, Str);
3745 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3747 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3748 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3749 if (ResTy == MatchOperand_Success) {
3750 assert(Operands.size() == 1);
3751 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3752 StartLoc = Operand.getStartLoc();
3753 EndLoc = Operand.getEndLoc();
3755 // AFAIK, we only support numeric registers and named GPR's in CFI
3757 // Don't worry about eating tokens before failing. Using an unrecognised
3758 // register is a parse error.
3759 if (Operand.isGPRAsmReg()) {
3760 // Resolve to GPR32 or GPR64 appropriately.
3761 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3764 return (RegNo == (unsigned)-1);
3767 assert(Operands.size() == 0);
3768 return (RegNo == (unsigned)-1);
3771 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3772 MCAsmParser &Parser = getParser();
3775 unsigned NumOfLParen = 0;
3777 while (getLexer().getKind() == AsmToken::LParen) {
3782 switch (getLexer().getKind()) {
3785 case AsmToken::Identifier:
3786 case AsmToken::LParen:
3787 case AsmToken::Integer:
3788 case AsmToken::Minus:
3789 case AsmToken::Plus:
3791 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3793 Result = (getParser().parseExpression(Res));
3794 while (getLexer().getKind() == AsmToken::RParen)
3797 case AsmToken::Percent:
3798 Result = parseRelocOperand(Res);
3803 MipsAsmParser::OperandMatchResultTy
3804 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3805 MCAsmParser &Parser = getParser();
3806 DEBUG(dbgs() << "parseMemOperand\n");
3807 const MCExpr *IdVal = nullptr;
3809 bool isParenExpr = false;
3810 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3811 // First operand is the offset.
3812 S = Parser.getTok().getLoc();
3814 if (getLexer().getKind() == AsmToken::LParen) {
3819 if (getLexer().getKind() != AsmToken::Dollar) {
3820 if (parseMemOffset(IdVal, isParenExpr))
3821 return MatchOperand_ParseFail;
3823 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3824 if (Tok.isNot(AsmToken::LParen)) {
3825 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3826 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3828 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3829 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3830 return MatchOperand_Success;
3832 if (Tok.is(AsmToken::EndOfStatement)) {
3834 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3836 // Zero register assumed, add a memory operand with ZERO as its base.
3837 // "Base" will be managed by k_Memory.
3838 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3841 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3842 return MatchOperand_Success;
3844 Error(Parser.getTok().getLoc(), "'(' expected");
3845 return MatchOperand_ParseFail;
3848 Parser.Lex(); // Eat the '(' token.
3851 Res = parseAnyRegister(Operands);
3852 if (Res != MatchOperand_Success)
3855 if (Parser.getTok().isNot(AsmToken::RParen)) {
3856 Error(Parser.getTok().getLoc(), "')' expected");
3857 return MatchOperand_ParseFail;
3860 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3862 Parser.Lex(); // Eat the ')' token.
3865 IdVal = MCConstantExpr::create(0, getContext());
3867 // Replace the register operand with the memory operand.
3868 std::unique_ptr<MipsOperand> op(
3869 static_cast<MipsOperand *>(Operands.back().release()));
3870 // Remove the register from the operands.
3871 // "op" will be managed by k_Memory.
3872 Operands.pop_back();
3873 // Add the memory operand.
3874 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3876 if (IdVal->evaluateAsAbsolute(Imm))
3877 IdVal = MCConstantExpr::create(Imm, getContext());
3878 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3879 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3883 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3884 return MatchOperand_Success;
3887 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3888 MCAsmParser &Parser = getParser();
3889 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3891 SMLoc S = Parser.getTok().getLoc();
3893 if (Sym->isVariable())
3894 Expr = Sym->getVariableValue();
3897 if (Expr->getKind() == MCExpr::SymbolRef) {
3898 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3899 StringRef DefSymbol = Ref->getSymbol().getName();
3900 if (DefSymbol.startswith("$")) {
3901 OperandMatchResultTy ResTy =
3902 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3903 if (ResTy == MatchOperand_Success) {
3906 } else if (ResTy == MatchOperand_ParseFail)
3907 llvm_unreachable("Should never ParseFail");
3910 } else if (Expr->getKind() == MCExpr::Constant) {
3912 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3914 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3921 MipsAsmParser::OperandMatchResultTy
3922 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3923 StringRef Identifier,
3925 int Index = matchCPURegisterName(Identifier);
3927 Operands.push_back(MipsOperand::createGPRReg(
3928 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3929 return MatchOperand_Success;
3932 Index = matchHWRegsRegisterName(Identifier);
3934 Operands.push_back(MipsOperand::createHWRegsReg(
3935 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3936 return MatchOperand_Success;
3939 Index = matchFPURegisterName(Identifier);
3941 Operands.push_back(MipsOperand::createFGRReg(
3942 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3943 return MatchOperand_Success;
3946 Index = matchFCCRegisterName(Identifier);
3948 Operands.push_back(MipsOperand::createFCCReg(
3949 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3950 return MatchOperand_Success;
3953 Index = matchACRegisterName(Identifier);
3955 Operands.push_back(MipsOperand::createACCReg(
3956 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3957 return MatchOperand_Success;
3960 Index = matchMSA128RegisterName(Identifier);
3962 Operands.push_back(MipsOperand::createMSA128Reg(
3963 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3964 return MatchOperand_Success;
3967 Index = matchMSA128CtrlRegisterName(Identifier);
3969 Operands.push_back(MipsOperand::createMSACtrlReg(
3970 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3971 return MatchOperand_Success;
3974 return MatchOperand_NoMatch;
3977 MipsAsmParser::OperandMatchResultTy
3978 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3979 MCAsmParser &Parser = getParser();
3980 auto Token = Parser.getLexer().peekTok(false);
3982 if (Token.is(AsmToken::Identifier)) {
3983 DEBUG(dbgs() << ".. identifier\n");
3984 StringRef Identifier = Token.getIdentifier();
3985 OperandMatchResultTy ResTy =
3986 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3988 } else if (Token.is(AsmToken::Integer)) {
3989 DEBUG(dbgs() << ".. integer\n");
3990 Operands.push_back(MipsOperand::createNumericReg(
3991 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3993 return MatchOperand_Success;
3996 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3998 return MatchOperand_NoMatch;
4001 MipsAsmParser::OperandMatchResultTy
4002 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4003 MCAsmParser &Parser = getParser();
4004 DEBUG(dbgs() << "parseAnyRegister\n");
4006 auto Token = Parser.getTok();
4008 SMLoc S = Token.getLoc();
4010 if (Token.isNot(AsmToken::Dollar)) {
4011 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4012 if (Token.is(AsmToken::Identifier)) {
4013 if (searchSymbolAlias(Operands))
4014 return MatchOperand_Success;
4016 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4017 return MatchOperand_NoMatch;
4019 DEBUG(dbgs() << ".. $\n");
4021 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4022 if (ResTy == MatchOperand_Success) {
4024 Parser.Lex(); // identifier
4029 MipsAsmParser::OperandMatchResultTy
4030 MipsAsmParser::parseImm(OperandVector &Operands) {
4031 MCAsmParser &Parser = getParser();
4032 switch (getLexer().getKind()) {
4034 return MatchOperand_NoMatch;
4035 case AsmToken::LParen:
4036 case AsmToken::Minus:
4037 case AsmToken::Plus:
4038 case AsmToken::Integer:
4039 case AsmToken::Tilde:
4040 case AsmToken::String:
4044 const MCExpr *IdVal;
4045 SMLoc S = Parser.getTok().getLoc();
4046 if (getParser().parseExpression(IdVal))
4047 return MatchOperand_ParseFail;
4049 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4050 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4051 return MatchOperand_Success;
4054 MipsAsmParser::OperandMatchResultTy
4055 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4056 MCAsmParser &Parser = getParser();
4057 DEBUG(dbgs() << "parseJumpTarget\n");
4059 SMLoc S = getLexer().getLoc();
4061 // Integers and expressions are acceptable
4062 OperandMatchResultTy ResTy = parseImm(Operands);
4063 if (ResTy != MatchOperand_NoMatch)
4066 // Registers are a valid target and have priority over symbols.
4067 ResTy = parseAnyRegister(Operands);
4068 if (ResTy != MatchOperand_NoMatch)
4071 const MCExpr *Expr = nullptr;
4072 if (Parser.parseExpression(Expr)) {
4073 // We have no way of knowing if a symbol was consumed so we must ParseFail
4074 return MatchOperand_ParseFail;
4077 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4078 return MatchOperand_Success;
4081 MipsAsmParser::OperandMatchResultTy
4082 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4083 MCAsmParser &Parser = getParser();
4084 const MCExpr *IdVal;
4085 // If the first token is '$' we may have register operand.
4086 if (Parser.getTok().is(AsmToken::Dollar))
4087 return MatchOperand_NoMatch;
4088 SMLoc S = Parser.getTok().getLoc();
4089 if (getParser().parseExpression(IdVal))
4090 return MatchOperand_ParseFail;
4091 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4092 assert(MCE && "Unexpected MCExpr type.");
4093 int64_t Val = MCE->getValue();
4094 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4095 Operands.push_back(MipsOperand::CreateImm(
4096 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4097 return MatchOperand_Success;
4100 MipsAsmParser::OperandMatchResultTy
4101 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4102 MCAsmParser &Parser = getParser();
4103 switch (getLexer().getKind()) {
4105 return MatchOperand_NoMatch;
4106 case AsmToken::LParen:
4107 case AsmToken::Plus:
4108 case AsmToken::Minus:
4109 case AsmToken::Integer:
4114 SMLoc S = Parser.getTok().getLoc();
4116 if (getParser().parseExpression(Expr))
4117 return MatchOperand_ParseFail;
4120 if (!Expr->evaluateAsAbsolute(Val)) {
4121 Error(S, "expected immediate value");
4122 return MatchOperand_ParseFail;
4125 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4126 // and because the CPU always adds one to the immediate field, the allowed
4127 // range becomes 1..4. We'll only check the range here and will deal
4128 // with the addition/subtraction when actually decoding/encoding
4130 if (Val < 1 || Val > 4) {
4131 Error(S, "immediate not in range (1..4)");
4132 return MatchOperand_ParseFail;
4136 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4137 return MatchOperand_Success;
4140 MipsAsmParser::OperandMatchResultTy
4141 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4142 MCAsmParser &Parser = getParser();
4143 SmallVector<unsigned, 10> Regs;
4145 unsigned PrevReg = Mips::NoRegister;
4146 bool RegRange = false;
4147 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4149 if (Parser.getTok().isNot(AsmToken::Dollar))
4150 return MatchOperand_ParseFail;
4152 SMLoc S = Parser.getTok().getLoc();
4153 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4154 SMLoc E = getLexer().getLoc();
4155 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4156 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4158 // Remove last register operand because registers from register range
4159 // should be inserted first.
4160 if (RegNo == Mips::RA) {
4161 Regs.push_back(RegNo);
4163 unsigned TmpReg = PrevReg + 1;
4164 while (TmpReg <= RegNo) {
4165 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4166 Error(E, "invalid register operand");
4167 return MatchOperand_ParseFail;
4171 Regs.push_back(TmpReg++);
4177 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4178 (RegNo != Mips::RA)) {
4179 Error(E, "$16 or $31 expected");
4180 return MatchOperand_ParseFail;
4181 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4182 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4183 Error(E, "invalid register operand");
4184 return MatchOperand_ParseFail;
4185 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4186 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4187 Error(E, "consecutive register numbers expected");
4188 return MatchOperand_ParseFail;
4191 Regs.push_back(RegNo);
4194 if (Parser.getTok().is(AsmToken::Minus))
4197 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4198 !Parser.getTok().isNot(AsmToken::Comma)) {
4199 Error(E, "',' or '-' expected");
4200 return MatchOperand_ParseFail;
4203 Lex(); // Consume comma or minus
4204 if (Parser.getTok().isNot(AsmToken::Dollar))
4210 SMLoc E = Parser.getTok().getLoc();
4211 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4212 parseMemOperand(Operands);
4213 return MatchOperand_Success;
4216 MipsAsmParser::OperandMatchResultTy
4217 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4218 MCAsmParser &Parser = getParser();
4220 SMLoc S = Parser.getTok().getLoc();
4221 if (parseAnyRegister(Operands) != MatchOperand_Success)
4222 return MatchOperand_ParseFail;
4224 SMLoc E = Parser.getTok().getLoc();
4225 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4226 unsigned Reg = Op.getGPR32Reg();
4227 Operands.pop_back();
4228 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4229 return MatchOperand_Success;
4232 MipsAsmParser::OperandMatchResultTy
4233 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4234 MCAsmParser &Parser = getParser();
4235 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4236 SmallVector<unsigned, 10> Regs;
4238 if (Parser.getTok().isNot(AsmToken::Dollar))
4239 return MatchOperand_ParseFail;
4241 SMLoc S = Parser.getTok().getLoc();
4243 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4244 return MatchOperand_ParseFail;
4246 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4247 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4248 Regs.push_back(RegNo);
4250 SMLoc E = Parser.getTok().getLoc();
4251 if (Parser.getTok().isNot(AsmToken::Comma)) {
4252 Error(E, "',' expected");
4253 return MatchOperand_ParseFail;
4259 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4260 return MatchOperand_ParseFail;
4262 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4263 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4264 Regs.push_back(RegNo);
4266 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4268 return MatchOperand_Success;
4271 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4273 MCSymbolRefExpr::VariantKind VK =
4274 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4275 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4276 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4277 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4278 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4279 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4280 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4281 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4282 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4283 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4284 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4285 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4286 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4287 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4288 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4289 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4290 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4291 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4292 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4293 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4294 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4295 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4296 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4297 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4298 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4299 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4300 .Default(MCSymbolRefExpr::VK_None);
4302 assert(VK != MCSymbolRefExpr::VK_None);
4307 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4309 /// ::= '(', register, ')'
4310 /// handle it before we iterate so we don't get tripped up by the lack of
4312 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4313 MCAsmParser &Parser = getParser();
4314 if (getLexer().is(AsmToken::LParen)) {
4316 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4318 if (parseOperand(Operands, Name)) {
4319 SMLoc Loc = getLexer().getLoc();
4320 Parser.eatToEndOfStatement();
4321 return Error(Loc, "unexpected token in argument list");
4323 if (Parser.getTok().isNot(AsmToken::RParen)) {
4324 SMLoc Loc = getLexer().getLoc();
4325 Parser.eatToEndOfStatement();
4326 return Error(Loc, "unexpected token, expected ')'");
4329 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4335 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4336 /// either one of these.
4337 /// ::= '[', register, ']'
4338 /// ::= '[', integer, ']'
4339 /// handle it before we iterate so we don't get tripped up by the lack of
4341 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4342 OperandVector &Operands) {
4343 MCAsmParser &Parser = getParser();
4344 if (getLexer().is(AsmToken::LBrac)) {
4346 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4348 if (parseOperand(Operands, Name)) {
4349 SMLoc Loc = getLexer().getLoc();
4350 Parser.eatToEndOfStatement();
4351 return Error(Loc, "unexpected token in argument list");
4353 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4354 SMLoc Loc = getLexer().getLoc();
4355 Parser.eatToEndOfStatement();
4356 return Error(Loc, "unexpected token, expected ']'");
4359 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4365 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4366 SMLoc NameLoc, OperandVector &Operands) {
4367 MCAsmParser &Parser = getParser();
4368 DEBUG(dbgs() << "ParseInstruction\n");
4370 // We have reached first instruction, module directive are now forbidden.
4371 getTargetStreamer().forbidModuleDirective();
4373 // Check if we have valid mnemonic
4374 if (!mnemonicIsValid(Name, 0)) {
4375 Parser.eatToEndOfStatement();
4376 return Error(NameLoc, "unknown instruction");
4378 // First operand in MCInst is instruction mnemonic.
4379 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4381 // Read the remaining operands.
4382 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4383 // Read the first operand.
4384 if (parseOperand(Operands, Name)) {
4385 SMLoc Loc = getLexer().getLoc();
4386 Parser.eatToEndOfStatement();
4387 return Error(Loc, "unexpected token in argument list");
4389 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4391 // AFAIK, parenthesis suffixes are never on the first operand
4393 while (getLexer().is(AsmToken::Comma)) {
4394 Parser.Lex(); // Eat the comma.
4395 // Parse and remember the operand.
4396 if (parseOperand(Operands, Name)) {
4397 SMLoc Loc = getLexer().getLoc();
4398 Parser.eatToEndOfStatement();
4399 return Error(Loc, "unexpected token in argument list");
4401 // Parse bracket and parenthesis suffixes before we iterate
4402 if (getLexer().is(AsmToken::LBrac)) {
4403 if (parseBracketSuffix(Name, Operands))
4405 } else if (getLexer().is(AsmToken::LParen) &&
4406 parseParenSuffix(Name, Operands))
4410 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4411 SMLoc Loc = getLexer().getLoc();
4412 Parser.eatToEndOfStatement();
4413 return Error(Loc, "unexpected token in argument list");
4415 Parser.Lex(); // Consume the EndOfStatement.
4419 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4420 MCAsmParser &Parser = getParser();
4421 SMLoc Loc = getLexer().getLoc();
4422 Parser.eatToEndOfStatement();
4423 return Error(Loc, ErrorMsg);
4426 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4427 return Error(Loc, ErrorMsg);
4430 bool MipsAsmParser::parseSetNoAtDirective() {
4431 MCAsmParser &Parser = getParser();
4432 // Line should look like: ".set noat".
4434 // Set the $at register to $0.
4435 AssemblerOptions.back()->setATRegIndex(0);
4437 Parser.Lex(); // Eat "noat".
4439 // If this is not the end of the statement, report an error.
4440 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4441 reportParseError("unexpected token, expected end of statement");
4445 getTargetStreamer().emitDirectiveSetNoAt();
4446 Parser.Lex(); // Consume the EndOfStatement.
4450 bool MipsAsmParser::parseSetAtDirective() {
4451 // Line can be: ".set at", which sets $at to $1
4452 // or ".set at=$reg", which sets $at to $reg.
4453 MCAsmParser &Parser = getParser();
4454 Parser.Lex(); // Eat "at".
4456 if (getLexer().is(AsmToken::EndOfStatement)) {
4457 // No register was specified, so we set $at to $1.
4458 AssemblerOptions.back()->setATRegIndex(1);
4460 getTargetStreamer().emitDirectiveSetAt();
4461 Parser.Lex(); // Consume the EndOfStatement.
4465 if (getLexer().isNot(AsmToken::Equal)) {
4466 reportParseError("unexpected token, expected equals sign");
4469 Parser.Lex(); // Eat "=".
4471 if (getLexer().isNot(AsmToken::Dollar)) {
4472 if (getLexer().is(AsmToken::EndOfStatement)) {
4473 reportParseError("no register specified");
4476 reportParseError("unexpected token, expected dollar sign '$'");
4480 Parser.Lex(); // Eat "$".
4482 // Find out what "reg" is.
4484 const AsmToken &Reg = Parser.getTok();
4485 if (Reg.is(AsmToken::Identifier)) {
4486 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4487 } else if (Reg.is(AsmToken::Integer)) {
4488 AtRegNo = Reg.getIntVal();
4490 reportParseError("unexpected token, expected identifier or integer");
4494 // Check if $reg is a valid register. If it is, set $at to $reg.
4495 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4496 reportParseError("invalid register");
4499 Parser.Lex(); // Eat "reg".
4501 // If this is not the end of the statement, report an error.
4502 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4503 reportParseError("unexpected token, expected end of statement");
4507 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4509 Parser.Lex(); // Consume the EndOfStatement.
4513 bool MipsAsmParser::parseSetReorderDirective() {
4514 MCAsmParser &Parser = getParser();
4516 // If this is not the end of the statement, report an error.
4517 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4518 reportParseError("unexpected token, expected end of statement");
4521 AssemblerOptions.back()->setReorder();
4522 getTargetStreamer().emitDirectiveSetReorder();
4523 Parser.Lex(); // Consume the EndOfStatement.
4527 bool MipsAsmParser::parseSetNoReorderDirective() {
4528 MCAsmParser &Parser = getParser();
4530 // If this is not the end of the statement, report an error.
4531 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4532 reportParseError("unexpected token, expected end of statement");
4535 AssemblerOptions.back()->setNoReorder();
4536 getTargetStreamer().emitDirectiveSetNoReorder();
4537 Parser.Lex(); // Consume the EndOfStatement.
4541 bool MipsAsmParser::parseSetMacroDirective() {
4542 MCAsmParser &Parser = getParser();
4544 // If this is not the end of the statement, report an error.
4545 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4546 reportParseError("unexpected token, expected end of statement");
4549 AssemblerOptions.back()->setMacro();
4550 getTargetStreamer().emitDirectiveSetMacro();
4551 Parser.Lex(); // Consume the EndOfStatement.
4555 bool MipsAsmParser::parseSetNoMacroDirective() {
4556 MCAsmParser &Parser = getParser();
4558 // If this is not the end of the statement, report an error.
4559 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4560 reportParseError("unexpected token, expected end of statement");
4563 if (AssemblerOptions.back()->isReorder()) {
4564 reportParseError("`noreorder' must be set before `nomacro'");
4567 AssemblerOptions.back()->setNoMacro();
4568 getTargetStreamer().emitDirectiveSetNoMacro();
4569 Parser.Lex(); // Consume the EndOfStatement.
4573 bool MipsAsmParser::parseSetMsaDirective() {
4574 MCAsmParser &Parser = getParser();
4577 // If this is not the end of the statement, report an error.
4578 if (getLexer().isNot(AsmToken::EndOfStatement))
4579 return reportParseError("unexpected token, expected end of statement");
4581 setFeatureBits(Mips::FeatureMSA, "msa");
4582 getTargetStreamer().emitDirectiveSetMsa();
4586 bool MipsAsmParser::parseSetNoMsaDirective() {
4587 MCAsmParser &Parser = getParser();
4590 // If this is not the end of the statement, report an error.
4591 if (getLexer().isNot(AsmToken::EndOfStatement))
4592 return reportParseError("unexpected token, expected end of statement");
4594 clearFeatureBits(Mips::FeatureMSA, "msa");
4595 getTargetStreamer().emitDirectiveSetNoMsa();
4599 bool MipsAsmParser::parseSetNoDspDirective() {
4600 MCAsmParser &Parser = getParser();
4601 Parser.Lex(); // Eat "nodsp".
4603 // If this is not the end of the statement, report an error.
4604 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4605 reportParseError("unexpected token, expected end of statement");
4609 clearFeatureBits(Mips::FeatureDSP, "dsp");
4610 getTargetStreamer().emitDirectiveSetNoDsp();
4614 bool MipsAsmParser::parseSetMips16Directive() {
4615 MCAsmParser &Parser = getParser();
4616 Parser.Lex(); // Eat "mips16".
4618 // If this is not the end of the statement, report an error.
4619 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4620 reportParseError("unexpected token, expected end of statement");
4624 setFeatureBits(Mips::FeatureMips16, "mips16");
4625 getTargetStreamer().emitDirectiveSetMips16();
4626 Parser.Lex(); // Consume the EndOfStatement.
4630 bool MipsAsmParser::parseSetNoMips16Directive() {
4631 MCAsmParser &Parser = getParser();
4632 Parser.Lex(); // Eat "nomips16".
4634 // If this is not the end of the statement, report an error.
4635 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4636 reportParseError("unexpected token, expected end of statement");
4640 clearFeatureBits(Mips::FeatureMips16, "mips16");
4641 getTargetStreamer().emitDirectiveSetNoMips16();
4642 Parser.Lex(); // Consume the EndOfStatement.
4646 bool MipsAsmParser::parseSetFpDirective() {
4647 MCAsmParser &Parser = getParser();
4648 MipsABIFlagsSection::FpABIKind FpAbiVal;
4649 // Line can be: .set fp=32
4652 Parser.Lex(); // Eat fp token
4653 AsmToken Tok = Parser.getTok();
4654 if (Tok.isNot(AsmToken::Equal)) {
4655 reportParseError("unexpected token, expected equals sign '='");
4658 Parser.Lex(); // Eat '=' token.
4659 Tok = Parser.getTok();
4661 if (!parseFpABIValue(FpAbiVal, ".set"))
4664 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4665 reportParseError("unexpected token, expected end of statement");
4668 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4669 Parser.Lex(); // Consume the EndOfStatement.
4673 bool MipsAsmParser::parseSetOddSPRegDirective() {
4674 MCAsmParser &Parser = getParser();
4676 Parser.Lex(); // Eat "oddspreg".
4677 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4678 reportParseError("unexpected token, expected end of statement");
4682 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4683 getTargetStreamer().emitDirectiveSetOddSPReg();
4687 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4688 MCAsmParser &Parser = getParser();
4690 Parser.Lex(); // Eat "nooddspreg".
4691 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4692 reportParseError("unexpected token, expected end of statement");
4696 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4697 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4701 bool MipsAsmParser::parseSetPopDirective() {
4702 MCAsmParser &Parser = getParser();
4703 SMLoc Loc = getLexer().getLoc();
4706 if (getLexer().isNot(AsmToken::EndOfStatement))
4707 return reportParseError("unexpected token, expected end of statement");
4709 // Always keep an element on the options "stack" to prevent the user
4710 // from changing the initial options. This is how we remember them.
4711 if (AssemblerOptions.size() == 2)
4712 return reportParseError(Loc, ".set pop with no .set push");
4714 AssemblerOptions.pop_back();
4715 setAvailableFeatures(
4716 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4717 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4719 getTargetStreamer().emitDirectiveSetPop();
4723 bool MipsAsmParser::parseSetPushDirective() {
4724 MCAsmParser &Parser = getParser();
4726 if (getLexer().isNot(AsmToken::EndOfStatement))
4727 return reportParseError("unexpected token, expected end of statement");
4729 // Create a copy of the current assembler options environment and push it.
4730 AssemblerOptions.push_back(
4731 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4733 getTargetStreamer().emitDirectiveSetPush();
4737 bool MipsAsmParser::parseSetSoftFloatDirective() {
4738 MCAsmParser &Parser = getParser();
4740 if (getLexer().isNot(AsmToken::EndOfStatement))
4741 return reportParseError("unexpected token, expected end of statement");
4743 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4744 getTargetStreamer().emitDirectiveSetSoftFloat();
4748 bool MipsAsmParser::parseSetHardFloatDirective() {
4749 MCAsmParser &Parser = getParser();
4751 if (getLexer().isNot(AsmToken::EndOfStatement))
4752 return reportParseError("unexpected token, expected end of statement");
4754 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4755 getTargetStreamer().emitDirectiveSetHardFloat();
4759 bool MipsAsmParser::parseSetAssignment() {
4761 const MCExpr *Value;
4762 MCAsmParser &Parser = getParser();
4764 if (Parser.parseIdentifier(Name))
4765 reportParseError("expected identifier after .set");
4767 if (getLexer().isNot(AsmToken::Comma))
4768 return reportParseError("unexpected token, expected comma");
4771 if (Parser.parseExpression(Value))
4772 return reportParseError("expected valid expression after comma");
4774 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4775 Sym->setVariableValue(Value);
4780 bool MipsAsmParser::parseSetMips0Directive() {
4781 MCAsmParser &Parser = getParser();
4783 if (getLexer().isNot(AsmToken::EndOfStatement))
4784 return reportParseError("unexpected token, expected end of statement");
4786 // Reset assembler options to their initial values.
4787 setAvailableFeatures(
4788 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4789 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4790 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4792 getTargetStreamer().emitDirectiveSetMips0();
4796 bool MipsAsmParser::parseSetArchDirective() {
4797 MCAsmParser &Parser = getParser();
4799 if (getLexer().isNot(AsmToken::Equal))
4800 return reportParseError("unexpected token, expected equals sign");
4804 if (Parser.parseIdentifier(Arch))
4805 return reportParseError("expected arch identifier");
4807 StringRef ArchFeatureName =
4808 StringSwitch<StringRef>(Arch)
4809 .Case("mips1", "mips1")
4810 .Case("mips2", "mips2")
4811 .Case("mips3", "mips3")
4812 .Case("mips4", "mips4")
4813 .Case("mips5", "mips5")
4814 .Case("mips32", "mips32")
4815 .Case("mips32r2", "mips32r2")
4816 .Case("mips32r3", "mips32r3")
4817 .Case("mips32r5", "mips32r5")
4818 .Case("mips32r6", "mips32r6")
4819 .Case("mips64", "mips64")
4820 .Case("mips64r2", "mips64r2")
4821 .Case("mips64r3", "mips64r3")
4822 .Case("mips64r5", "mips64r5")
4823 .Case("mips64r6", "mips64r6")
4824 .Case("cnmips", "cnmips")
4825 .Case("r4000", "mips3") // This is an implementation of Mips3.
4828 if (ArchFeatureName.empty())
4829 return reportParseError("unsupported architecture");
4831 selectArch(ArchFeatureName);
4832 getTargetStreamer().emitDirectiveSetArch(Arch);
4836 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4837 MCAsmParser &Parser = getParser();
4839 if (getLexer().isNot(AsmToken::EndOfStatement))
4840 return reportParseError("unexpected token, expected end of statement");
4844 llvm_unreachable("Unimplemented feature");
4845 case Mips::FeatureDSP:
4846 setFeatureBits(Mips::FeatureDSP, "dsp");
4847 getTargetStreamer().emitDirectiveSetDsp();
4849 case Mips::FeatureMicroMips:
4850 getTargetStreamer().emitDirectiveSetMicroMips();
4852 case Mips::FeatureMips1:
4853 selectArch("mips1");
4854 getTargetStreamer().emitDirectiveSetMips1();
4856 case Mips::FeatureMips2:
4857 selectArch("mips2");
4858 getTargetStreamer().emitDirectiveSetMips2();
4860 case Mips::FeatureMips3:
4861 selectArch("mips3");
4862 getTargetStreamer().emitDirectiveSetMips3();
4864 case Mips::FeatureMips4:
4865 selectArch("mips4");
4866 getTargetStreamer().emitDirectiveSetMips4();
4868 case Mips::FeatureMips5:
4869 selectArch("mips5");
4870 getTargetStreamer().emitDirectiveSetMips5();
4872 case Mips::FeatureMips32:
4873 selectArch("mips32");
4874 getTargetStreamer().emitDirectiveSetMips32();
4876 case Mips::FeatureMips32r2:
4877 selectArch("mips32r2");
4878 getTargetStreamer().emitDirectiveSetMips32R2();
4880 case Mips::FeatureMips32r3:
4881 selectArch("mips32r3");
4882 getTargetStreamer().emitDirectiveSetMips32R3();
4884 case Mips::FeatureMips32r5:
4885 selectArch("mips32r5");
4886 getTargetStreamer().emitDirectiveSetMips32R5();
4888 case Mips::FeatureMips32r6:
4889 selectArch("mips32r6");
4890 getTargetStreamer().emitDirectiveSetMips32R6();
4892 case Mips::FeatureMips64:
4893 selectArch("mips64");
4894 getTargetStreamer().emitDirectiveSetMips64();
4896 case Mips::FeatureMips64r2:
4897 selectArch("mips64r2");
4898 getTargetStreamer().emitDirectiveSetMips64R2();
4900 case Mips::FeatureMips64r3:
4901 selectArch("mips64r3");
4902 getTargetStreamer().emitDirectiveSetMips64R3();
4904 case Mips::FeatureMips64r5:
4905 selectArch("mips64r5");
4906 getTargetStreamer().emitDirectiveSetMips64R5();
4908 case Mips::FeatureMips64r6:
4909 selectArch("mips64r6");
4910 getTargetStreamer().emitDirectiveSetMips64R6();
4916 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4917 MCAsmParser &Parser = getParser();
4918 if (getLexer().isNot(AsmToken::Comma)) {
4919 SMLoc Loc = getLexer().getLoc();
4920 Parser.eatToEndOfStatement();
4921 return Error(Loc, ErrorStr);
4924 Parser.Lex(); // Eat the comma.
4928 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4929 // In this class, it is only used for .cprestore.
4930 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4931 // MipsTargetELFStreamer and MipsAsmParser.
4932 bool MipsAsmParser::isPicAndNotNxxAbi() {
4933 return inPicMode() && !(isABI_N32() || isABI_N64());
4936 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4937 if (AssemblerOptions.back()->isReorder())
4938 Warning(Loc, ".cpload should be inside a noreorder section");
4940 if (inMips16Mode()) {
4941 reportParseError(".cpload is not supported in Mips16 mode");
4945 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4946 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4947 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4948 reportParseError("expected register containing function address");
4952 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4953 if (!RegOpnd.isGPRAsmReg()) {
4954 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4958 // If this is not the end of the statement, report an error.
4959 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4960 reportParseError("unexpected token, expected end of statement");
4964 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4968 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4969 MCAsmParser &Parser = getParser();
4971 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4972 // is used in non-PIC mode.
4974 if (inMips16Mode()) {
4975 reportParseError(".cprestore is not supported in Mips16 mode");
4979 // Get the stack offset value.
4980 const MCExpr *StackOffset;
4981 int64_t StackOffsetVal;
4982 if (Parser.parseExpression(StackOffset)) {
4983 reportParseError("expected stack offset value");
4987 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4988 reportParseError("stack offset is not an absolute expression");
4992 if (StackOffsetVal < 0) {
4993 Warning(Loc, ".cprestore with negative stack offset has no effect");
4994 IsCpRestoreSet = false;
4996 IsCpRestoreSet = true;
4997 CpRestoreOffset = StackOffsetVal;
5000 // If this is not the end of the statement, report an error.
5001 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5002 reportParseError("unexpected token, expected end of statement");
5006 // Store the $gp on the stack.
5007 SmallVector<MCInst, 3> StoreInsts;
5008 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5011 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
5012 Parser.Lex(); // Consume the EndOfStatement.
5016 bool MipsAsmParser::parseDirectiveCPSetup() {
5017 MCAsmParser &Parser = getParser();
5020 bool SaveIsReg = true;
5022 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5023 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5024 if (ResTy == MatchOperand_NoMatch) {
5025 reportParseError("expected register containing function address");
5026 Parser.eatToEndOfStatement();
5030 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5031 if (!FuncRegOpnd.isGPRAsmReg()) {
5032 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5033 Parser.eatToEndOfStatement();
5037 FuncReg = FuncRegOpnd.getGPR32Reg();
5040 if (!eatComma("unexpected token, expected comma"))
5043 ResTy = parseAnyRegister(TmpReg);
5044 if (ResTy == MatchOperand_NoMatch) {
5045 const MCExpr *OffsetExpr;
5047 SMLoc ExprLoc = getLexer().getLoc();
5049 if (Parser.parseExpression(OffsetExpr) ||
5050 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5051 reportParseError(ExprLoc, "expected save register or stack offset");
5052 Parser.eatToEndOfStatement();
5059 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5060 if (!SaveOpnd.isGPRAsmReg()) {
5061 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5062 Parser.eatToEndOfStatement();
5065 Save = SaveOpnd.getGPR32Reg();
5068 if (!eatComma("unexpected token, expected comma"))
5072 if (Parser.parseExpression(Expr)) {
5073 reportParseError("expected expression");
5077 if (Expr->getKind() != MCExpr::SymbolRef) {
5078 reportParseError("expected symbol");
5081 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5083 CpSaveLocation = Save;
5084 CpSaveLocationIsRegister = SaveIsReg;
5086 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5091 bool MipsAsmParser::parseDirectiveCPReturn() {
5092 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5093 CpSaveLocationIsRegister);
5097 bool MipsAsmParser::parseDirectiveNaN() {
5098 MCAsmParser &Parser = getParser();
5099 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5100 const AsmToken &Tok = Parser.getTok();
5102 if (Tok.getString() == "2008") {
5104 getTargetStreamer().emitDirectiveNaN2008();
5106 } else if (Tok.getString() == "legacy") {
5108 getTargetStreamer().emitDirectiveNaNLegacy();
5112 // If we don't recognize the option passed to the .nan
5113 // directive (e.g. no option or unknown option), emit an error.
5114 reportParseError("invalid option in .nan directive");
5118 bool MipsAsmParser::parseDirectiveSet() {
5119 MCAsmParser &Parser = getParser();
5120 // Get the next token.
5121 const AsmToken &Tok = Parser.getTok();
5123 if (Tok.getString() == "noat") {
5124 return parseSetNoAtDirective();
5125 } else if (Tok.getString() == "at") {
5126 return parseSetAtDirective();
5127 } else if (Tok.getString() == "arch") {
5128 return parseSetArchDirective();
5129 } else if (Tok.getString() == "fp") {
5130 return parseSetFpDirective();
5131 } else if (Tok.getString() == "oddspreg") {
5132 return parseSetOddSPRegDirective();
5133 } else if (Tok.getString() == "nooddspreg") {
5134 return parseSetNoOddSPRegDirective();
5135 } else if (Tok.getString() == "pop") {
5136 return parseSetPopDirective();
5137 } else if (Tok.getString() == "push") {
5138 return parseSetPushDirective();
5139 } else if (Tok.getString() == "reorder") {
5140 return parseSetReorderDirective();
5141 } else if (Tok.getString() == "noreorder") {
5142 return parseSetNoReorderDirective();
5143 } else if (Tok.getString() == "macro") {
5144 return parseSetMacroDirective();
5145 } else if (Tok.getString() == "nomacro") {
5146 return parseSetNoMacroDirective();
5147 } else if (Tok.getString() == "mips16") {
5148 return parseSetMips16Directive();
5149 } else if (Tok.getString() == "nomips16") {
5150 return parseSetNoMips16Directive();
5151 } else if (Tok.getString() == "nomicromips") {
5152 getTargetStreamer().emitDirectiveSetNoMicroMips();
5153 Parser.eatToEndOfStatement();
5155 } else if (Tok.getString() == "micromips") {
5156 return parseSetFeature(Mips::FeatureMicroMips);
5157 } else if (Tok.getString() == "mips0") {
5158 return parseSetMips0Directive();
5159 } else if (Tok.getString() == "mips1") {
5160 return parseSetFeature(Mips::FeatureMips1);
5161 } else if (Tok.getString() == "mips2") {
5162 return parseSetFeature(Mips::FeatureMips2);
5163 } else if (Tok.getString() == "mips3") {
5164 return parseSetFeature(Mips::FeatureMips3);
5165 } else if (Tok.getString() == "mips4") {
5166 return parseSetFeature(Mips::FeatureMips4);
5167 } else if (Tok.getString() == "mips5") {
5168 return parseSetFeature(Mips::FeatureMips5);
5169 } else if (Tok.getString() == "mips32") {
5170 return parseSetFeature(Mips::FeatureMips32);
5171 } else if (Tok.getString() == "mips32r2") {
5172 return parseSetFeature(Mips::FeatureMips32r2);
5173 } else if (Tok.getString() == "mips32r3") {
5174 return parseSetFeature(Mips::FeatureMips32r3);
5175 } else if (Tok.getString() == "mips32r5") {
5176 return parseSetFeature(Mips::FeatureMips32r5);
5177 } else if (Tok.getString() == "mips32r6") {
5178 return parseSetFeature(Mips::FeatureMips32r6);
5179 } else if (Tok.getString() == "mips64") {
5180 return parseSetFeature(Mips::FeatureMips64);
5181 } else if (Tok.getString() == "mips64r2") {
5182 return parseSetFeature(Mips::FeatureMips64r2);
5183 } else if (Tok.getString() == "mips64r3") {
5184 return parseSetFeature(Mips::FeatureMips64r3);
5185 } else if (Tok.getString() == "mips64r5") {
5186 return parseSetFeature(Mips::FeatureMips64r5);
5187 } else if (Tok.getString() == "mips64r6") {
5188 return parseSetFeature(Mips::FeatureMips64r6);
5189 } else if (Tok.getString() == "dsp") {
5190 return parseSetFeature(Mips::FeatureDSP);
5191 } else if (Tok.getString() == "nodsp") {
5192 return parseSetNoDspDirective();
5193 } else if (Tok.getString() == "msa") {
5194 return parseSetMsaDirective();
5195 } else if (Tok.getString() == "nomsa") {
5196 return parseSetNoMsaDirective();
5197 } else if (Tok.getString() == "softfloat") {
5198 return parseSetSoftFloatDirective();
5199 } else if (Tok.getString() == "hardfloat") {
5200 return parseSetHardFloatDirective();
5202 // It is just an identifier, look for an assignment.
5203 parseSetAssignment();
5210 /// parseDataDirective
5211 /// ::= .word [ expression (, expression)* ]
5212 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5213 MCAsmParser &Parser = getParser();
5214 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5216 const MCExpr *Value;
5217 if (getParser().parseExpression(Value))
5220 getParser().getStreamer().EmitValue(Value, Size);
5222 if (getLexer().is(AsmToken::EndOfStatement))
5225 if (getLexer().isNot(AsmToken::Comma))
5226 return Error(L, "unexpected token, expected comma");
5235 /// parseDirectiveGpWord
5236 /// ::= .gpword local_sym
5237 bool MipsAsmParser::parseDirectiveGpWord() {
5238 MCAsmParser &Parser = getParser();
5239 const MCExpr *Value;
5240 // EmitGPRel32Value requires an expression, so we are using base class
5241 // method to evaluate the expression.
5242 if (getParser().parseExpression(Value))
5244 getParser().getStreamer().EmitGPRel32Value(Value);
5246 if (getLexer().isNot(AsmToken::EndOfStatement))
5247 return Error(getLexer().getLoc(),
5248 "unexpected token, expected end of statement");
5249 Parser.Lex(); // Eat EndOfStatement token.
5253 /// parseDirectiveGpDWord
5254 /// ::= .gpdword local_sym
5255 bool MipsAsmParser::parseDirectiveGpDWord() {
5256 MCAsmParser &Parser = getParser();
5257 const MCExpr *Value;
5258 // EmitGPRel64Value requires an expression, so we are using base class
5259 // method to evaluate the expression.
5260 if (getParser().parseExpression(Value))
5262 getParser().getStreamer().EmitGPRel64Value(Value);
5264 if (getLexer().isNot(AsmToken::EndOfStatement))
5265 return Error(getLexer().getLoc(),
5266 "unexpected token, expected end of statement");
5267 Parser.Lex(); // Eat EndOfStatement token.
5271 bool MipsAsmParser::parseDirectiveOption() {
5272 MCAsmParser &Parser = getParser();
5273 // Get the option token.
5274 AsmToken Tok = Parser.getTok();
5275 // At the moment only identifiers are supported.
5276 if (Tok.isNot(AsmToken::Identifier)) {
5277 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5278 Parser.eatToEndOfStatement();
5282 StringRef Option = Tok.getIdentifier();
5284 if (Option == "pic0") {
5285 // MipsAsmParser needs to know if the current PIC mode changes.
5286 IsPicEnabled = false;
5288 getTargetStreamer().emitDirectiveOptionPic0();
5290 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5291 Error(Parser.getTok().getLoc(),
5292 "unexpected token, expected end of statement");
5293 Parser.eatToEndOfStatement();
5298 if (Option == "pic2") {
5299 // MipsAsmParser needs to know if the current PIC mode changes.
5300 IsPicEnabled = true;
5302 getTargetStreamer().emitDirectiveOptionPic2();
5304 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5305 Error(Parser.getTok().getLoc(),
5306 "unexpected token, expected end of statement");
5307 Parser.eatToEndOfStatement();
5313 Warning(Parser.getTok().getLoc(),
5314 "unknown option, expected 'pic0' or 'pic2'");
5315 Parser.eatToEndOfStatement();
5319 /// parseInsnDirective
5321 bool MipsAsmParser::parseInsnDirective() {
5322 // If this is not the end of the statement, report an error.
5323 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5324 reportParseError("unexpected token, expected end of statement");
5328 // The actual label marking happens in
5329 // MipsELFStreamer::createPendingLabelRelocs().
5330 getTargetStreamer().emitDirectiveInsn();
5332 getParser().Lex(); // Eat EndOfStatement token.
5336 /// parseDirectiveModule
5337 /// ::= .module oddspreg
5338 /// ::= .module nooddspreg
5339 /// ::= .module fp=value
5340 /// ::= .module softfloat
5341 /// ::= .module hardfloat
5342 bool MipsAsmParser::parseDirectiveModule() {
5343 MCAsmParser &Parser = getParser();
5344 MCAsmLexer &Lexer = getLexer();
5345 SMLoc L = Lexer.getLoc();
5347 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5348 // TODO : get a better message.
5349 reportParseError(".module directive must appear before any code");
5354 if (Parser.parseIdentifier(Option)) {
5355 reportParseError("expected .module option identifier");
5359 if (Option == "oddspreg") {
5360 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5362 // Synchronize the abiflags information with the FeatureBits information we
5364 getTargetStreamer().updateABIInfo(*this);
5366 // If printing assembly, use the recently updated abiflags information.
5367 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5368 // emitted at the end).
5369 getTargetStreamer().emitDirectiveModuleOddSPReg();
5371 // If this is not the end of the statement, report an error.
5372 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5373 reportParseError("unexpected token, expected end of statement");
5377 return false; // parseDirectiveModule has finished successfully.
5378 } else if (Option == "nooddspreg") {
5380 Error(L, "'.module nooddspreg' requires the O32 ABI");
5384 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5386 // Synchronize the abiflags information with the FeatureBits information we
5388 getTargetStreamer().updateABIInfo(*this);
5390 // If printing assembly, use the recently updated abiflags information.
5391 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5392 // emitted at the end).
5393 getTargetStreamer().emitDirectiveModuleOddSPReg();
5395 // If this is not the end of the statement, report an error.
5396 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5397 reportParseError("unexpected token, expected end of statement");
5401 return false; // parseDirectiveModule has finished successfully.
5402 } else if (Option == "fp") {
5403 return parseDirectiveModuleFP();
5404 } else if (Option == "softfloat") {
5405 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5407 // Synchronize the ABI Flags information with the FeatureBits information we
5409 getTargetStreamer().updateABIInfo(*this);
5411 // If printing assembly, use the recently updated ABI Flags information.
5412 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5414 getTargetStreamer().emitDirectiveModuleSoftFloat();
5416 // If this is not the end of the statement, report an error.
5417 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5418 reportParseError("unexpected token, expected end of statement");
5422 return false; // parseDirectiveModule has finished successfully.
5423 } else if (Option == "hardfloat") {
5424 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5426 // Synchronize the ABI Flags information with the FeatureBits information we
5428 getTargetStreamer().updateABIInfo(*this);
5430 // If printing assembly, use the recently updated ABI Flags information.
5431 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5433 getTargetStreamer().emitDirectiveModuleHardFloat();
5435 // If this is not the end of the statement, report an error.
5436 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5437 reportParseError("unexpected token, expected end of statement");
5441 return false; // parseDirectiveModule has finished successfully.
5443 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5447 /// parseDirectiveModuleFP
5451 bool MipsAsmParser::parseDirectiveModuleFP() {
5452 MCAsmParser &Parser = getParser();
5453 MCAsmLexer &Lexer = getLexer();
5455 if (Lexer.isNot(AsmToken::Equal)) {
5456 reportParseError("unexpected token, expected equals sign '='");
5459 Parser.Lex(); // Eat '=' token.
5461 MipsABIFlagsSection::FpABIKind FpABI;
5462 if (!parseFpABIValue(FpABI, ".module"))
5465 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5466 reportParseError("unexpected token, expected end of statement");
5470 // Synchronize the abiflags information with the FeatureBits information we
5472 getTargetStreamer().updateABIInfo(*this);
5474 // If printing assembly, use the recently updated abiflags information.
5475 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5476 // emitted at the end).
5477 getTargetStreamer().emitDirectiveModuleFP();
5479 Parser.Lex(); // Consume the EndOfStatement.
5483 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5484 StringRef Directive) {
5485 MCAsmParser &Parser = getParser();
5486 MCAsmLexer &Lexer = getLexer();
5487 bool ModuleLevelOptions = Directive == ".module";
5489 if (Lexer.is(AsmToken::Identifier)) {
5490 StringRef Value = Parser.getTok().getString();
5493 if (Value != "xx") {
5494 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5499 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5503 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5504 if (ModuleLevelOptions) {
5505 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5506 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5508 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5509 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5514 if (Lexer.is(AsmToken::Integer)) {
5515 unsigned Value = Parser.getTok().getIntVal();
5518 if (Value != 32 && Value != 64) {
5519 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5525 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5529 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5530 if (ModuleLevelOptions) {
5531 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5532 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5534 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5535 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5538 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5539 if (ModuleLevelOptions) {
5540 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5541 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5543 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5544 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5554 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5555 MCAsmParser &Parser = getParser();
5556 StringRef IDVal = DirectiveID.getString();
5558 if (IDVal == ".cpload")
5559 return parseDirectiveCpLoad(DirectiveID.getLoc());
5560 if (IDVal == ".cprestore")
5561 return parseDirectiveCpRestore(DirectiveID.getLoc());
5562 if (IDVal == ".dword") {
5563 parseDataDirective(8, DirectiveID.getLoc());
5566 if (IDVal == ".ent") {
5567 StringRef SymbolName;
5569 if (Parser.parseIdentifier(SymbolName)) {
5570 reportParseError("expected identifier after .ent");
5574 // There's an undocumented extension that allows an integer to
5575 // follow the name of the procedure which AFAICS is ignored by GAS.
5576 // Example: .ent foo,2
5577 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5578 if (getLexer().isNot(AsmToken::Comma)) {
5579 // Even though we accept this undocumented extension for compatibility
5580 // reasons, the additional integer argument does not actually change
5581 // the behaviour of the '.ent' directive, so we would like to discourage
5582 // its use. We do this by not referring to the extended version in
5583 // error messages which are not directly related to its use.
5584 reportParseError("unexpected token, expected end of statement");
5587 Parser.Lex(); // Eat the comma.
5588 const MCExpr *DummyNumber;
5589 int64_t DummyNumberVal;
5590 // If the user was explicitly trying to use the extended version,
5591 // we still give helpful extension-related error messages.
5592 if (Parser.parseExpression(DummyNumber)) {
5593 reportParseError("expected number after comma");
5596 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5597 reportParseError("expected an absolute expression after comma");
5602 // If this is not the end of the statement, report an error.
5603 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5604 reportParseError("unexpected token, expected end of statement");
5608 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5610 getTargetStreamer().emitDirectiveEnt(*Sym);
5612 IsCpRestoreSet = false;
5616 if (IDVal == ".end") {
5617 StringRef SymbolName;
5619 if (Parser.parseIdentifier(SymbolName)) {
5620 reportParseError("expected identifier after .end");
5624 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5625 reportParseError("unexpected token, expected end of statement");
5629 if (CurrentFn == nullptr) {
5630 reportParseError(".end used without .ent");
5634 if ((SymbolName != CurrentFn->getName())) {
5635 reportParseError(".end symbol does not match .ent symbol");
5639 getTargetStreamer().emitDirectiveEnd(SymbolName);
5640 CurrentFn = nullptr;
5641 IsCpRestoreSet = false;
5645 if (IDVal == ".frame") {
5646 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5647 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5648 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5649 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5650 reportParseError("expected stack register");
5654 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5655 if (!StackRegOpnd.isGPRAsmReg()) {
5656 reportParseError(StackRegOpnd.getStartLoc(),
5657 "expected general purpose register");
5660 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5662 if (Parser.getTok().is(AsmToken::Comma))
5665 reportParseError("unexpected token, expected comma");
5669 // Parse the frame size.
5670 const MCExpr *FrameSize;
5671 int64_t FrameSizeVal;
5673 if (Parser.parseExpression(FrameSize)) {
5674 reportParseError("expected frame size value");
5678 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5679 reportParseError("frame size not an absolute expression");
5683 if (Parser.getTok().is(AsmToken::Comma))
5686 reportParseError("unexpected token, expected comma");
5690 // Parse the return register.
5692 ResTy = parseAnyRegister(TmpReg);
5693 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5694 reportParseError("expected return register");
5698 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5699 if (!ReturnRegOpnd.isGPRAsmReg()) {
5700 reportParseError(ReturnRegOpnd.getStartLoc(),
5701 "expected general purpose register");
5705 // If this is not the end of the statement, report an error.
5706 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5707 reportParseError("unexpected token, expected end of statement");
5711 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5712 ReturnRegOpnd.getGPR32Reg());
5713 IsCpRestoreSet = false;
5717 if (IDVal == ".set") {
5718 return parseDirectiveSet();
5721 if (IDVal == ".mask" || IDVal == ".fmask") {
5722 // .mask bitmask, frame_offset
5723 // bitmask: One bit for each register used.
5724 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5725 // first register is expected to be saved.
5727 // .mask 0x80000000, -4
5728 // .fmask 0x80000000, -4
5731 // Parse the bitmask
5732 const MCExpr *BitMask;
5735 if (Parser.parseExpression(BitMask)) {
5736 reportParseError("expected bitmask value");
5740 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5741 reportParseError("bitmask not an absolute expression");
5745 if (Parser.getTok().is(AsmToken::Comma))
5748 reportParseError("unexpected token, expected comma");
5752 // Parse the frame_offset
5753 const MCExpr *FrameOffset;
5754 int64_t FrameOffsetVal;
5756 if (Parser.parseExpression(FrameOffset)) {
5757 reportParseError("expected frame offset value");
5761 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5762 reportParseError("frame offset not an absolute expression");
5766 // If this is not the end of the statement, report an error.
5767 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5768 reportParseError("unexpected token, expected end of statement");
5772 if (IDVal == ".mask")
5773 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5775 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5779 if (IDVal == ".nan")
5780 return parseDirectiveNaN();
5782 if (IDVal == ".gpword") {
5783 parseDirectiveGpWord();
5787 if (IDVal == ".gpdword") {
5788 parseDirectiveGpDWord();
5792 if (IDVal == ".word") {
5793 parseDataDirective(4, DirectiveID.getLoc());
5797 if (IDVal == ".option")
5798 return parseDirectiveOption();
5800 if (IDVal == ".abicalls") {
5801 getTargetStreamer().emitDirectiveAbiCalls();
5802 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5803 Error(Parser.getTok().getLoc(),
5804 "unexpected token, expected end of statement");
5806 Parser.eatToEndOfStatement();
5811 if (IDVal == ".cpsetup")
5812 return parseDirectiveCPSetup();
5814 if (IDVal == ".cpreturn")
5815 return parseDirectiveCPReturn();
5817 if (IDVal == ".module")
5818 return parseDirectiveModule();
5820 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5821 return parseInternalDirectiveReallowModule();
5823 if (IDVal == ".insn")
5824 return parseInsnDirective();
5829 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5830 // If this is not the end of the statement, report an error.
5831 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5832 reportParseError("unexpected token, expected end of statement");
5836 getTargetStreamer().reallowModuleDirective();
5838 getParser().Lex(); // Eat EndOfStatement token.
5842 extern "C" void LLVMInitializeMipsAsmParser() {
5843 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5844 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5845 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5846 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5849 #define GET_REGISTER_MATCHER
5850 #define GET_MATCHER_IMPLEMENTATION
5851 #include "MipsGenAsmMatcher.inc"