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);
111 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
112 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113 // nullptr, which indicates that no function is currently
114 // selected. This usually happens after an '.end func'
120 unsigned CpSaveLocation;
121 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
122 bool CpSaveLocationIsRegister;
124 // Print a warning along with its fix-it message at the given range.
125 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
126 SMRange Range, bool ShowColors = true);
128 #define GET_ASSEMBLER_HEADER
129 #include "MipsGenAsmMatcher.inc"
131 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
133 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
134 OperandVector &Operands, MCStreamer &Out,
136 bool MatchingInlineAsm) override;
138 /// Parse a register as used in CFI directives
139 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
141 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
143 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
145 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
146 SMLoc NameLoc, OperandVector &Operands) override;
148 bool ParseDirective(AsmToken DirectiveID) override;
150 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
152 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
153 StringRef Identifier, SMLoc S);
154 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
156 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
157 OperandMatchResultTy parseImm(OperandVector &Operands);
158 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
159 OperandMatchResultTy parseInvNum(OperandVector &Operands);
160 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
161 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
162 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
163 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
165 bool searchSymbolAlias(OperandVector &Operands);
167 bool parseOperand(OperandVector &, StringRef Mnemonic);
169 enum MacroExpanderResultTy {
175 // Expands assembly pseudo instructions.
176 MacroExpanderResultTy
177 tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
178 SmallVectorImpl<MCInst> &Instructions);
180 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
183 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
184 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
185 SmallVectorImpl<MCInst> &Instructions);
187 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
188 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
191 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
192 SmallVectorImpl<MCInst> &Instructions);
194 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
195 const MCOperand &Offset, bool Is32BitAddress,
196 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
198 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
199 SmallVectorImpl<MCInst> &Instructions);
201 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
205 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions);
208 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
215 SmallVectorImpl<MCInst> &Instructions);
217 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
218 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
221 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
222 SmallVectorImpl<MCInst> &Instructions);
224 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
225 SmallVectorImpl<MCInst> &Instructions);
227 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
228 SmallVectorImpl<MCInst> &Instructions);
229 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc,
230 SmallVectorImpl<MCInst> &Instructions);
231 bool expandDRotation(MCInst &Inst, SMLoc IDLoc,
232 SmallVectorImpl<MCInst> &Instructions);
233 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
234 SmallVectorImpl<MCInst> &Instructions);
236 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
237 SmallVectorImpl<MCInst> &Instructions);
239 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
240 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
242 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
243 SmallVectorImpl<MCInst> &Instructions);
245 bool reportParseError(Twine ErrorMsg);
246 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
248 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
249 bool parseRelocOperand(const MCExpr *&Res);
251 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
253 bool isEvaluated(const MCExpr *Expr);
254 bool parseSetMips0Directive();
255 bool parseSetArchDirective();
256 bool parseSetFeature(uint64_t Feature);
257 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
258 bool parseDirectiveCpLoad(SMLoc Loc);
259 bool parseDirectiveCpRestore(SMLoc Loc);
260 bool parseDirectiveCPSetup();
261 bool parseDirectiveCPReturn();
262 bool parseDirectiveNaN();
263 bool parseDirectiveSet();
264 bool parseDirectiveOption();
265 bool parseInsnDirective();
267 bool parseSetAtDirective();
268 bool parseSetNoAtDirective();
269 bool parseSetMacroDirective();
270 bool parseSetNoMacroDirective();
271 bool parseSetMsaDirective();
272 bool parseSetNoMsaDirective();
273 bool parseSetNoDspDirective();
274 bool parseSetReorderDirective();
275 bool parseSetNoReorderDirective();
276 bool parseSetMips16Directive();
277 bool parseSetNoMips16Directive();
278 bool parseSetFpDirective();
279 bool parseSetOddSPRegDirective();
280 bool parseSetNoOddSPRegDirective();
281 bool parseSetPopDirective();
282 bool parseSetPushDirective();
283 bool parseSetSoftFloatDirective();
284 bool parseSetHardFloatDirective();
286 bool parseSetAssignment();
288 bool parseDataDirective(unsigned Size, SMLoc L);
289 bool parseDirectiveGpWord();
290 bool parseDirectiveGpDWord();
291 bool parseDirectiveModule();
292 bool parseDirectiveModuleFP();
293 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
294 StringRef Directive);
296 bool parseInternalDirectiveReallowModule();
298 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
300 bool eatComma(StringRef ErrorStr);
302 int matchCPURegisterName(StringRef Symbol);
304 int matchHWRegsRegisterName(StringRef Symbol);
306 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
308 int matchFPURegisterName(StringRef Name);
310 int matchFCCRegisterName(StringRef Name);
312 int matchACRegisterName(StringRef Name);
314 int matchMSA128RegisterName(StringRef Name);
316 int matchMSA128CtrlRegisterName(StringRef Name);
318 unsigned getReg(int RC, int RegNo);
320 unsigned getGPR(int RegNo);
322 /// Returns the internal register number for the current AT. Also checks if
323 /// the current AT is unavailable (set to $0) and gives an error if it is.
324 /// This should be used in pseudo-instruction expansions which need AT.
325 unsigned getATReg(SMLoc Loc);
327 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
328 SmallVectorImpl<MCInst> &Instructions);
330 // Helper function that checks if the value of a vector index is within the
331 // boundaries of accepted values for each RegisterKind
332 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
333 bool validateMSAIndex(int Val, int RegKind);
335 // Selects a new architecture by updating the FeatureBits with the necessary
336 // info including implied dependencies.
337 // Internally, it clears all the feature bits related to *any* architecture
338 // and selects the new one using the ToggleFeature functionality of the
339 // MCSubtargetInfo object that handles implied dependencies. The reason we
340 // clear all the arch related bits manually is because ToggleFeature only
341 // clears the features that imply the feature being cleared and not the
342 // features implied by the feature being cleared. This is easier to see
344 // --------------------------------------------------
345 // | Feature | Implies |
346 // | -------------------------------------------------|
347 // | FeatureMips1 | None |
348 // | FeatureMips2 | FeatureMips1 |
349 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
350 // | FeatureMips4 | FeatureMips3 |
352 // --------------------------------------------------
354 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
355 // FeatureMipsGP64 | FeatureMips1)
356 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
357 void selectArch(StringRef ArchFeature) {
358 MCSubtargetInfo &STI = copySTI();
359 FeatureBitset FeatureBits = STI.getFeatureBits();
360 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
361 STI.setFeatureBits(FeatureBits);
362 setAvailableFeatures(
363 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
364 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
367 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
368 if (!(getSTI().getFeatureBits()[Feature])) {
369 MCSubtargetInfo &STI = copySTI();
370 setAvailableFeatures(
371 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
372 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
376 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
377 if (getSTI().getFeatureBits()[Feature]) {
378 MCSubtargetInfo &STI = copySTI();
379 setAvailableFeatures(
380 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
381 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
385 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
386 setFeatureBits(Feature, FeatureString);
387 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
390 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
391 clearFeatureBits(Feature, FeatureString);
392 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
396 enum MipsMatchResultTy {
397 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
398 #define GET_OPERAND_DIAGNOSTIC_TYPES
399 #include "MipsGenAsmMatcher.inc"
400 #undef GET_OPERAND_DIAGNOSTIC_TYPES
403 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
404 const MCInstrInfo &MII, const MCTargetOptions &Options)
405 : MCTargetAsmParser(Options, sti),
406 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
407 sti.getCPU(), Options)) {
408 MCAsmParserExtension::Initialize(parser);
410 parser.addAliasForDirective(".asciiz", ".asciz");
412 // Initialize the set of available features.
413 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
415 // Remember the initial assembler options. The user can not modify these.
416 AssemblerOptions.push_back(
417 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
419 // Create an assembler options environment for the user to modify.
420 AssemblerOptions.push_back(
421 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
423 getTargetStreamer().updateABIInfo(*this);
425 if (!isABI_O32() && !useOddSPReg() != 0)
426 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
431 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
433 IsCpRestoreSet = false;
434 CpRestoreOffset = -1;
436 Triple TheTriple(sti.getTargetTriple());
437 if ((TheTriple.getArch() == Triple::mips) ||
438 (TheTriple.getArch() == Triple::mips64))
439 IsLittleEndian = false;
441 IsLittleEndian = true;
444 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
445 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
447 bool isGP64bit() const {
448 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
450 bool isFP64bit() const {
451 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
453 const MipsABIInfo &getABI() const { return ABI; }
454 bool isABI_N32() const { return ABI.IsN32(); }
455 bool isABI_N64() const { return ABI.IsN64(); }
456 bool isABI_O32() const { return ABI.IsO32(); }
457 bool isABI_FPXX() const {
458 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
461 bool useOddSPReg() const {
462 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
465 bool inMicroMipsMode() const {
466 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
468 bool hasMips1() const {
469 return getSTI().getFeatureBits()[Mips::FeatureMips1];
471 bool hasMips2() const {
472 return getSTI().getFeatureBits()[Mips::FeatureMips2];
474 bool hasMips3() const {
475 return getSTI().getFeatureBits()[Mips::FeatureMips3];
477 bool hasMips4() const {
478 return getSTI().getFeatureBits()[Mips::FeatureMips4];
480 bool hasMips5() const {
481 return getSTI().getFeatureBits()[Mips::FeatureMips5];
483 bool hasMips32() const {
484 return getSTI().getFeatureBits()[Mips::FeatureMips32];
486 bool hasMips64() const {
487 return getSTI().getFeatureBits()[Mips::FeatureMips64];
489 bool hasMips32r2() const {
490 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
492 bool hasMips64r2() const {
493 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
495 bool hasMips32r3() const {
496 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
498 bool hasMips64r3() const {
499 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
501 bool hasMips32r5() const {
502 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
504 bool hasMips64r5() const {
505 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
507 bool hasMips32r6() const {
508 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
510 bool hasMips64r6() const {
511 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
514 bool hasDSP() const {
515 return getSTI().getFeatureBits()[Mips::FeatureDSP];
517 bool hasDSPR2() const {
518 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
520 bool hasDSPR3() const {
521 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
523 bool hasMSA() const {
524 return getSTI().getFeatureBits()[Mips::FeatureMSA];
526 bool hasCnMips() const {
527 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
534 bool inMips16Mode() const {
535 return getSTI().getFeatureBits()[Mips::FeatureMips16];
538 bool useTraps() const {
539 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
542 bool useSoftFloat() const {
543 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
546 /// Warn if RegIndex is the same as the current AT.
547 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
549 void warnIfNoMacro(SMLoc Loc);
551 bool isLittle() const { return IsLittleEndian; }
557 /// MipsOperand - Instances of this class represent a parsed Mips machine
559 class MipsOperand : public MCParsedAsmOperand {
561 /// Broad categories of register classes
562 /// The exact class is finalized by the render method.
564 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
565 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
567 RegKind_FCC = 4, /// FCC
568 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
569 RegKind_MSACtrl = 16, /// MSA control registers
570 RegKind_COP2 = 32, /// COP2
571 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
573 RegKind_CCR = 128, /// CCR
574 RegKind_HWRegs = 256, /// HWRegs
575 RegKind_COP3 = 512, /// COP3
576 RegKind_COP0 = 1024, /// COP0
577 /// Potentially any (e.g. $1)
578 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
579 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
580 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
585 k_Immediate, /// An immediate (possibly involving symbol references)
586 k_Memory, /// Base + Offset Memory Address
587 k_PhysRegister, /// A physical register from the Mips namespace
588 k_RegisterIndex, /// A register index in one or more RegKind.
589 k_Token, /// A simple token
590 k_RegList, /// A physical register list
591 k_RegPair /// A pair of physical register
595 MipsOperand(KindTy K, MipsAsmParser &Parser)
596 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
599 /// For diagnostics, and checking the assembler temporary
600 MipsAsmParser &AsmParser;
608 unsigned Num; /// Register Number
612 unsigned Index; /// Index into the register class
613 RegKind Kind; /// Bitfield of the kinds it could possibly be
614 const MCRegisterInfo *RegInfo;
627 SmallVector<unsigned, 10> *List;
632 struct PhysRegOp PhysReg;
633 struct RegIdxOp RegIdx;
636 struct RegListOp RegList;
639 SMLoc StartLoc, EndLoc;
641 /// Internal constructor for register kinds
642 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
643 const MCRegisterInfo *RegInfo,
645 MipsAsmParser &Parser) {
646 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
647 Op->RegIdx.Index = Index;
648 Op->RegIdx.RegInfo = RegInfo;
649 Op->RegIdx.Kind = RegKind;
656 /// Coerce the register to GPR32 and return the real register for the current
658 unsigned getGPR32Reg() const {
659 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
660 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
661 unsigned ClassID = Mips::GPR32RegClassID;
662 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
665 /// Coerce the register to GPR32 and return the real register for the current
667 unsigned getGPRMM16Reg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
669 unsigned ClassID = Mips::GPR32RegClassID;
670 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
673 /// Coerce the register to GPR64 and return the real register for the current
675 unsigned getGPR64Reg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
677 unsigned ClassID = Mips::GPR64RegClassID;
678 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
682 /// Coerce the register to AFGR64 and return the real register for the current
684 unsigned getAFGR64Reg() const {
685 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
686 if (RegIdx.Index % 2 != 0)
687 AsmParser.Warning(StartLoc, "Float register should be even.");
688 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
689 .getRegister(RegIdx.Index / 2);
692 /// Coerce the register to FGR64 and return the real register for the current
694 unsigned getFGR64Reg() const {
695 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
696 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
697 .getRegister(RegIdx.Index);
700 /// Coerce the register to FGR32 and return the real register for the current
702 unsigned getFGR32Reg() const {
703 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
704 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
705 .getRegister(RegIdx.Index);
708 /// Coerce the register to FGRH32 and return the real register for the current
710 unsigned getFGRH32Reg() const {
711 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
712 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
713 .getRegister(RegIdx.Index);
716 /// Coerce the register to FCC and return the real register for the current
718 unsigned getFCCReg() const {
719 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
720 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
721 .getRegister(RegIdx.Index);
724 /// Coerce the register to MSA128 and return the real register for the current
726 unsigned getMSA128Reg() const {
727 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
728 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
730 unsigned ClassID = Mips::MSA128BRegClassID;
731 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
734 /// Coerce the register to MSACtrl and return the real register for the
736 unsigned getMSACtrlReg() const {
737 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
738 unsigned ClassID = Mips::MSACtrlRegClassID;
739 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
742 /// Coerce the register to COP0 and return the real register for the
744 unsigned getCOP0Reg() const {
745 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
746 unsigned ClassID = Mips::COP0RegClassID;
747 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
750 /// Coerce the register to COP2 and return the real register for the
752 unsigned getCOP2Reg() const {
753 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
754 unsigned ClassID = Mips::COP2RegClassID;
755 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
758 /// Coerce the register to COP3 and return the real register for the
760 unsigned getCOP3Reg() const {
761 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
762 unsigned ClassID = Mips::COP3RegClassID;
763 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
766 /// Coerce the register to ACC64DSP and return the real register for the
768 unsigned getACC64DSPReg() const {
769 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
770 unsigned ClassID = Mips::ACC64DSPRegClassID;
771 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
774 /// Coerce the register to HI32DSP and return the real register for the
776 unsigned getHI32DSPReg() const {
777 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
778 unsigned ClassID = Mips::HI32DSPRegClassID;
779 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
782 /// Coerce the register to LO32DSP and return the real register for the
784 unsigned getLO32DSPReg() const {
785 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
786 unsigned ClassID = Mips::LO32DSPRegClassID;
787 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
790 /// Coerce the register to CCR and return the real register for the
792 unsigned getCCRReg() const {
793 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
794 unsigned ClassID = Mips::CCRRegClassID;
795 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
798 /// Coerce the register to HWRegs and return the real register for the
800 unsigned getHWRegsReg() const {
801 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
802 unsigned ClassID = Mips::HWRegsRegClassID;
803 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
807 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
808 // Add as immediate when possible. Null MCExpr = 0.
810 Inst.addOperand(MCOperand::createImm(0));
811 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
812 Inst.addOperand(MCOperand::createImm(CE->getValue()));
814 Inst.addOperand(MCOperand::createExpr(Expr));
817 void addRegOperands(MCInst &Inst, unsigned N) const {
818 llvm_unreachable("Use a custom parser instead");
821 /// Render the operand to an MCInst as a GPR32
822 /// Asserts if the wrong number of operands are requested, or the operand
823 /// is not a k_RegisterIndex compatible with RegKind_GPR
824 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
825 assert(N == 1 && "Invalid number of operands!");
826 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
829 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
830 assert(N == 1 && "Invalid number of operands!");
831 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
834 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
835 assert(N == 1 && "Invalid number of operands!");
836 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
839 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
840 assert(N == 1 && "Invalid number of operands!");
841 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
844 /// Render the operand to an MCInst as a GPR64
845 /// Asserts if the wrong number of operands are requested, or the operand
846 /// is not a k_RegisterIndex compatible with RegKind_GPR
847 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 1 && "Invalid number of operands!");
849 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
852 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
853 assert(N == 1 && "Invalid number of operands!");
854 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
857 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
858 assert(N == 1 && "Invalid number of operands!");
859 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
862 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
863 assert(N == 1 && "Invalid number of operands!");
864 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
865 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
866 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
867 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
871 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
872 assert(N == 1 && "Invalid number of operands!");
873 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
876 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
877 assert(N == 1 && "Invalid number of operands!");
878 Inst.addOperand(MCOperand::createReg(getFCCReg()));
881 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
882 assert(N == 1 && "Invalid number of operands!");
883 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
886 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
887 assert(N == 1 && "Invalid number of operands!");
888 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
891 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
892 assert(N == 1 && "Invalid number of operands!");
893 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
896 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
897 assert(N == 1 && "Invalid number of operands!");
898 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
901 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
902 assert(N == 1 && "Invalid number of operands!");
903 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
906 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
907 assert(N == 1 && "Invalid number of operands!");
908 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
911 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
912 assert(N == 1 && "Invalid number of operands!");
913 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
916 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
917 assert(N == 1 && "Invalid number of operands!");
918 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
921 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
922 assert(N == 1 && "Invalid number of operands!");
923 Inst.addOperand(MCOperand::createReg(getCCRReg()));
926 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
927 assert(N == 1 && "Invalid number of operands!");
928 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
931 template <unsigned Bits, int Offset = 0>
932 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
933 assert(N == 1 && "Invalid number of operands!");
934 uint64_t Imm = getConstantImm() - Offset;
935 Imm &= (1 << Bits) - 1;
937 Inst.addOperand(MCOperand::createImm(Imm));
940 void addImmOperands(MCInst &Inst, unsigned N) const {
941 assert(N == 1 && "Invalid number of operands!");
942 const MCExpr *Expr = getImm();
946 void addMemOperands(MCInst &Inst, unsigned N) const {
947 assert(N == 2 && "Invalid number of operands!");
949 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
950 ? getMemBase()->getGPR64Reg()
951 : getMemBase()->getGPR32Reg()));
953 const MCExpr *Expr = getMemOff();
957 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
958 assert(N == 2 && "Invalid number of operands!");
960 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
962 const MCExpr *Expr = getMemOff();
966 void addRegListOperands(MCInst &Inst, unsigned N) const {
967 assert(N == 1 && "Invalid number of operands!");
969 for (auto RegNo : getRegList())
970 Inst.addOperand(MCOperand::createReg(RegNo));
973 void addRegPairOperands(MCInst &Inst, unsigned N) const {
974 assert(N == 2 && "Invalid number of operands!");
975 unsigned RegNo = getRegPair();
976 Inst.addOperand(MCOperand::createReg(RegNo++));
977 Inst.addOperand(MCOperand::createReg(RegNo));
980 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
981 assert(N == 2 && "Invalid number of operands!");
982 for (auto RegNo : getRegList())
983 Inst.addOperand(MCOperand::createReg(RegNo));
986 bool isReg() const override {
987 // As a special case until we sort out the definition of div/divu, pretend
988 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
989 if (isGPRAsmReg() && RegIdx.Index == 0)
992 return Kind == k_PhysRegister;
994 bool isRegIdx() const { return Kind == k_RegisterIndex; }
995 bool isImm() const override { return Kind == k_Immediate; }
996 bool isConstantImm() const {
997 return isImm() && isa<MCConstantExpr>(getImm());
999 bool isConstantImmz() const {
1000 return isConstantImm() && getConstantImm() == 0;
1002 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1003 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1005 template <unsigned Bits> bool isUImm() const {
1006 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
1008 bool isToken() const override {
1009 // Note: It's not possible to pretend that other operand kinds are tokens.
1010 // The matcher emitter checks tokens first.
1011 return Kind == k_Token;
1013 bool isMem() const override { return Kind == k_Memory; }
1014 bool isConstantMemOff() const {
1015 return isMem() && isa<MCConstantExpr>(getMemOff());
1017 template <unsigned Bits> bool isMemWithSimmOffset() const {
1018 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1019 && getMemBase()->isGPRAsmReg();
1021 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
1022 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
1023 getMemBase()->isGPRAsmReg();
1025 bool isMemWithGRPMM16Base() const {
1026 return isMem() && getMemBase()->isMM16AsmReg();
1028 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1029 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1030 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1032 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1033 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1034 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1035 && (getMemBase()->getGPR32Reg() == Mips::SP);
1037 bool isUImm5Lsl2() const {
1038 return (isImm() && isConstantImm() && isShiftedUInt<5, 2>(getConstantImm()));
1040 bool isRegList16() const {
1044 int Size = RegList.List->size();
1045 if (Size < 2 || Size > 5)
1048 unsigned R0 = RegList.List->front();
1049 unsigned R1 = RegList.List->back();
1050 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1051 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1054 int PrevReg = *RegList.List->begin();
1055 for (int i = 1; i < Size - 1; i++) {
1056 int Reg = (*(RegList.List))[i];
1057 if ( Reg != PrevReg + 1)
1064 bool isInvNum() const { return Kind == k_Immediate; }
1065 bool isLSAImm() const {
1066 if (!isConstantImm())
1068 int64_t Val = getConstantImm();
1069 return 1 <= Val && Val <= 4;
1071 bool isRegList() const { return Kind == k_RegList; }
1072 bool isMovePRegPair() const {
1073 if (Kind != k_RegList || RegList.List->size() != 2)
1076 unsigned R0 = RegList.List->front();
1077 unsigned R1 = RegList.List->back();
1079 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1080 (R0 == Mips::A1 && R1 == Mips::A3) ||
1081 (R0 == Mips::A2 && R1 == Mips::A3) ||
1082 (R0 == Mips::A0 && R1 == Mips::S5) ||
1083 (R0 == Mips::A0 && R1 == Mips::S6) ||
1084 (R0 == Mips::A0 && R1 == Mips::A1) ||
1085 (R0 == Mips::A0 && R1 == Mips::A2) ||
1086 (R0 == Mips::A0 && R1 == Mips::A3))
1092 StringRef getToken() const {
1093 assert(Kind == k_Token && "Invalid access!");
1094 return StringRef(Tok.Data, Tok.Length);
1096 bool isRegPair() const { return Kind == k_RegPair; }
1098 unsigned getReg() const override {
1099 // As a special case until we sort out the definition of div/divu, pretend
1100 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1101 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1102 RegIdx.Kind & RegKind_GPR)
1103 return getGPR32Reg(); // FIXME: GPR64 too
1105 assert(Kind == k_PhysRegister && "Invalid access!");
1109 const MCExpr *getImm() const {
1110 assert((Kind == k_Immediate) && "Invalid access!");
1114 int64_t getConstantImm() const {
1115 const MCExpr *Val = getImm();
1116 return static_cast<const MCConstantExpr *>(Val)->getValue();
1119 MipsOperand *getMemBase() const {
1120 assert((Kind == k_Memory) && "Invalid access!");
1124 const MCExpr *getMemOff() const {
1125 assert((Kind == k_Memory) && "Invalid access!");
1129 int64_t getConstantMemOff() const {
1130 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1133 const SmallVectorImpl<unsigned> &getRegList() const {
1134 assert((Kind == k_RegList) && "Invalid access!");
1135 return *(RegList.List);
1138 unsigned getRegPair() const {
1139 assert((Kind == k_RegPair) && "Invalid access!");
1140 return RegIdx.Index;
1143 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1144 MipsAsmParser &Parser) {
1145 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1146 Op->Tok.Data = Str.data();
1147 Op->Tok.Length = Str.size();
1153 /// Create a numeric register (e.g. $1). The exact register remains
1154 /// unresolved until an instruction successfully matches
1155 static std::unique_ptr<MipsOperand>
1156 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1157 SMLoc E, MipsAsmParser &Parser) {
1158 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1159 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1162 /// Create a register that is definitely a GPR.
1163 /// This is typically only used for named registers such as $gp.
1164 static std::unique_ptr<MipsOperand>
1165 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1166 MipsAsmParser &Parser) {
1167 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1170 /// Create a register that is definitely a FGR.
1171 /// This is typically only used for named registers such as $f0.
1172 static std::unique_ptr<MipsOperand>
1173 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1174 MipsAsmParser &Parser) {
1175 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1178 /// Create a register that is definitely a HWReg.
1179 /// This is typically only used for named registers such as $hwr_cpunum.
1180 static std::unique_ptr<MipsOperand>
1181 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1182 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1183 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1186 /// Create a register that is definitely an FCC.
1187 /// This is typically only used for named registers such as $fcc0.
1188 static std::unique_ptr<MipsOperand>
1189 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1190 MipsAsmParser &Parser) {
1191 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1194 /// Create a register that is definitely an ACC.
1195 /// This is typically only used for named registers such as $ac0.
1196 static std::unique_ptr<MipsOperand>
1197 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1198 MipsAsmParser &Parser) {
1199 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1202 /// Create a register that is definitely an MSA128.
1203 /// This is typically only used for named registers such as $w0.
1204 static std::unique_ptr<MipsOperand>
1205 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1206 SMLoc E, MipsAsmParser &Parser) {
1207 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1210 /// Create a register that is definitely an MSACtrl.
1211 /// This is typically only used for named registers such as $msaaccess.
1212 static std::unique_ptr<MipsOperand>
1213 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1214 SMLoc E, MipsAsmParser &Parser) {
1215 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1218 static std::unique_ptr<MipsOperand>
1219 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1220 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1227 static std::unique_ptr<MipsOperand>
1228 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1229 SMLoc E, MipsAsmParser &Parser) {
1230 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1231 Op->Mem.Base = Base.release();
1238 static std::unique_ptr<MipsOperand>
1239 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1240 MipsAsmParser &Parser) {
1241 assert (Regs.size() > 0 && "Empty list not allowed");
1243 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1244 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1245 Op->StartLoc = StartLoc;
1246 Op->EndLoc = EndLoc;
1250 static std::unique_ptr<MipsOperand>
1251 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1252 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1253 Op->RegIdx.Index = RegNo;
1259 bool isGPRAsmReg() const {
1260 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1262 bool isMM16AsmReg() const {
1263 if (!(isRegIdx() && RegIdx.Kind))
1265 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1266 || RegIdx.Index == 16 || RegIdx.Index == 17);
1268 bool isMM16AsmRegZero() const {
1269 if (!(isRegIdx() && RegIdx.Kind))
1271 return (RegIdx.Index == 0 ||
1272 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1273 RegIdx.Index == 17);
1275 bool isMM16AsmRegMoveP() const {
1276 if (!(isRegIdx() && RegIdx.Kind))
1278 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1279 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1281 bool isFGRAsmReg() const {
1282 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1283 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1285 bool isHWRegsAsmReg() const {
1286 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1288 bool isCCRAsmReg() const {
1289 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1291 bool isFCCAsmReg() const {
1292 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1294 if (!AsmParser.hasEightFccRegisters())
1295 return RegIdx.Index == 0;
1296 return RegIdx.Index <= 7;
1298 bool isACCAsmReg() const {
1299 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1301 bool isCOP0AsmReg() const {
1302 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1304 bool isCOP2AsmReg() const {
1305 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1307 bool isCOP3AsmReg() const {
1308 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1310 bool isMSA128AsmReg() const {
1311 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1313 bool isMSACtrlAsmReg() const {
1314 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1317 /// getStartLoc - Get the location of the first token of this operand.
1318 SMLoc getStartLoc() const override { return StartLoc; }
1319 /// getEndLoc - Get the location of the last token of this operand.
1320 SMLoc getEndLoc() const override { return EndLoc; }
1322 virtual ~MipsOperand() {
1330 delete RegList.List;
1331 case k_PhysRegister:
1332 case k_RegisterIndex:
1339 void print(raw_ostream &OS) const override {
1348 Mem.Base->print(OS);
1353 case k_PhysRegister:
1354 OS << "PhysReg<" << PhysReg.Num << ">";
1356 case k_RegisterIndex:
1357 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1364 for (auto Reg : (*RegList.List))
1369 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1373 }; // class MipsOperand
1377 extern const MCInstrDesc MipsInsts[];
1379 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1380 return MipsInsts[Opcode];
1383 static bool hasShortDelaySlot(unsigned Opcode) {
1386 case Mips::JALRS_MM:
1387 case Mips::JALRS16_MM:
1388 case Mips::BGEZALS_MM:
1389 case Mips::BLTZALS_MM:
1396 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1397 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1398 return &SRExpr->getSymbol();
1401 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1402 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1403 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1414 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1415 return getSingleMCSymbol(UExpr->getSubExpr());
1420 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1421 if (isa<MCSymbolRefExpr>(Expr))
1424 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1425 return countMCSymbolRefExpr(BExpr->getLHS()) +
1426 countMCSymbolRefExpr(BExpr->getRHS());
1428 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1429 return countMCSymbolRefExpr(UExpr->getSubExpr());
1435 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1436 SmallVectorImpl<MCInst> &Instructions) {
1438 tmpInst.setOpcode(Opcode);
1439 tmpInst.addOperand(MCOperand::createReg(Reg0));
1440 tmpInst.addOperand(Op1);
1441 tmpInst.setLoc(IDLoc);
1442 Instructions.push_back(tmpInst);
1445 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1446 SmallVectorImpl<MCInst> &Instructions) {
1447 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1450 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1451 SmallVectorImpl<MCInst> &Instructions) {
1452 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1455 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1456 SmallVectorImpl<MCInst> &Instructions) {
1458 tmpInst.setOpcode(Opcode);
1459 tmpInst.addOperand(MCOperand::createImm(Imm1));
1460 tmpInst.addOperand(MCOperand::createImm(Imm2));
1461 tmpInst.setLoc(IDLoc);
1462 Instructions.push_back(tmpInst);
1465 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1466 SmallVectorImpl<MCInst> &Instructions) {
1468 tmpInst.setOpcode(Opcode);
1469 tmpInst.addOperand(MCOperand::createReg(Reg0));
1470 tmpInst.setLoc(IDLoc);
1471 Instructions.push_back(tmpInst);
1474 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1475 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1477 tmpInst.setOpcode(Opcode);
1478 tmpInst.addOperand(MCOperand::createReg(Reg0));
1479 tmpInst.addOperand(MCOperand::createReg(Reg1));
1480 tmpInst.addOperand(Op2);
1481 tmpInst.setLoc(IDLoc);
1482 Instructions.push_back(tmpInst);
1485 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1486 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1487 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1491 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1492 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1493 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1497 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1498 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1499 if (ShiftAmount >= 32) {
1500 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1505 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1507 } // end anonymous namespace.
1509 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1510 SmallVectorImpl<MCInst> &Instructions) {
1511 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1512 bool ExpandedJalSym = false;
1516 if (MCID.isBranch() || MCID.isCall()) {
1517 const unsigned Opcode = Inst.getOpcode();
1527 assert(hasCnMips() && "instruction only valid for octeon cpus");
1534 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1535 Offset = Inst.getOperand(2);
1536 if (!Offset.isImm())
1537 break; // We'll deal with this situation later on when applying fixups.
1538 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1539 return Error(IDLoc, "branch target out of range");
1540 if (OffsetToAlignment(Offset.getImm(),
1541 1LL << (inMicroMipsMode() ? 1 : 2)))
1542 return Error(IDLoc, "branch to misaligned address");
1556 case Mips::BGEZAL_MM:
1557 case Mips::BLTZAL_MM:
1560 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1561 Offset = Inst.getOperand(1);
1562 if (!Offset.isImm())
1563 break; // We'll deal with this situation later on when applying fixups.
1564 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1565 return Error(IDLoc, "branch target out of range");
1566 if (OffsetToAlignment(Offset.getImm(),
1567 1LL << (inMicroMipsMode() ? 1 : 2)))
1568 return Error(IDLoc, "branch to misaligned address");
1570 case Mips::BEQZ16_MM:
1571 case Mips::BEQZC16_MMR6:
1572 case Mips::BNEZ16_MM:
1573 case Mips::BNEZC16_MMR6:
1574 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1575 Offset = Inst.getOperand(1);
1576 if (!Offset.isImm())
1577 break; // We'll deal with this situation later on when applying fixups.
1578 if (!isInt<8>(Offset.getImm()))
1579 return Error(IDLoc, "branch target out of range");
1580 if (OffsetToAlignment(Offset.getImm(), 2LL))
1581 return Error(IDLoc, "branch to misaligned address");
1586 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1587 // We still accept it but it is a normal nop.
1588 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1589 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1590 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1595 const unsigned Opcode = Inst.getOpcode();
1607 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1608 // The offset is handled above
1609 Opnd = Inst.getOperand(1);
1611 return Error(IDLoc, "expected immediate operand kind");
1612 Imm = Opnd.getImm();
1613 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1614 Opcode == Mips::BBIT1 ? 63 : 31))
1615 return Error(IDLoc, "immediate operand value out of range");
1617 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1619 Inst.getOperand(1).setImm(Imm - 32);
1627 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1629 Opnd = Inst.getOperand(3);
1631 return Error(IDLoc, "expected immediate operand kind");
1632 Imm = Opnd.getImm();
1633 if (Imm < 0 || Imm > 31)
1634 return Error(IDLoc, "immediate operand value out of range");
1636 Opnd = Inst.getOperand(2);
1638 return Error(IDLoc, "expected immediate operand kind");
1639 Imm = Opnd.getImm();
1640 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1641 Opcode == Mips::EXTS ? 63 : 31))
1642 return Error(IDLoc, "immediate operand value out of range");
1644 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1645 Inst.getOperand(2).setImm(Imm - 32);
1651 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1652 Opnd = Inst.getOperand(2);
1654 return Error(IDLoc, "expected immediate operand kind");
1655 Imm = Opnd.getImm();
1656 if (!isInt<10>(Imm))
1657 return Error(IDLoc, "immediate operand value out of range");
1662 // This expansion is not in a function called by tryExpandInstruction()
1663 // because the pseudo-instruction doesn't have a distinct opcode.
1664 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1666 warnIfNoMacro(IDLoc);
1668 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1670 // We can do this expansion if there's only 1 symbol in the argument
1672 if (countMCSymbolRefExpr(JalExpr) > 1)
1673 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1675 // FIXME: This is checking the expression can be handled by the later stages
1676 // of the assembler. We ought to leave it to those later stages but
1677 // we can't do that until we stop evaluateRelocExpr() rewriting the
1678 // expressions into non-equivalent forms.
1679 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1681 // FIXME: Add support for label+offset operands (currently causes an error).
1682 // FIXME: Add support for forward-declared local symbols.
1683 // FIXME: Add expansion for when the LargeGOT option is enabled.
1684 if (JalSym->isInSection() || JalSym->isTemporary()) {
1686 // If it's a local symbol and the O32 ABI is being used, we expand to:
1688 // R_(MICRO)MIPS_GOT16 label
1689 // addiu $25, $25, 0
1690 // R_(MICRO)MIPS_LO16 label
1692 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1693 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1695 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1696 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1697 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1698 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1699 } else if (isABI_N32() || isABI_N64()) {
1700 // If it's a local symbol and the N32/N64 ABIs are being used,
1702 // lw/ld $25, 0($gp)
1703 // R_(MICRO)MIPS_GOT_DISP label
1705 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1707 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1708 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1711 // If it's an external/weak symbol, we expand to:
1712 // lw/ld $25, 0($gp)
1713 // R_(MICRO)MIPS_CALL16 label
1715 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1717 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1718 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1722 if (IsCpRestoreSet && inMicroMipsMode())
1723 JalrInst.setOpcode(Mips::JALRS_MM);
1725 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1726 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1727 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1729 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1730 // This relocation is supposed to be an optimization hint for the linker
1731 // and is not necessary for correctness.
1734 ExpandedJalSym = true;
1737 if (MCID.mayLoad() || MCID.mayStore()) {
1738 // Check the offset of memory operand, if it is a symbol
1739 // reference or immediate we may have to expand instructions.
1740 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1741 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1742 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1743 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1744 MCOperand &Op = Inst.getOperand(i);
1746 int MemOffset = Op.getImm();
1747 if (MemOffset < -32768 || MemOffset > 32767) {
1748 // Offset can't exceed 16bit value.
1749 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1752 } else if (Op.isExpr()) {
1753 const MCExpr *Expr = Op.getExpr();
1754 if (Expr->getKind() == MCExpr::SymbolRef) {
1755 const MCSymbolRefExpr *SR =
1756 static_cast<const MCSymbolRefExpr *>(Expr);
1757 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1759 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1762 } else if (!isEvaluated(Expr)) {
1763 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1771 if (inMicroMipsMode()) {
1772 if (MCID.mayLoad()) {
1773 // Try to create 16-bit GP relative load instruction.
1774 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1775 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1776 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1777 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1778 MCOperand &Op = Inst.getOperand(i);
1780 int MemOffset = Op.getImm();
1781 MCOperand &DstReg = Inst.getOperand(0);
1782 MCOperand &BaseReg = Inst.getOperand(1);
1783 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1784 getContext().getRegisterInfo()->getRegClass(
1785 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1786 (BaseReg.getReg() == Mips::GP ||
1787 BaseReg.getReg() == Mips::GP_64)) {
1789 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1790 IDLoc, Instructions);
1798 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1803 switch (Inst.getOpcode()) {
1806 case Mips::ADDIUS5_MM:
1807 Opnd = Inst.getOperand(2);
1809 return Error(IDLoc, "expected immediate operand kind");
1810 Imm = Opnd.getImm();
1811 if (Imm < -8 || Imm > 7)
1812 return Error(IDLoc, "immediate operand value out of range");
1814 case Mips::ADDIUSP_MM:
1815 Opnd = Inst.getOperand(0);
1817 return Error(IDLoc, "expected immediate operand kind");
1818 Imm = Opnd.getImm();
1819 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1821 return Error(IDLoc, "immediate operand value out of range");
1823 case Mips::SLL16_MM:
1824 case Mips::SRL16_MM:
1825 Opnd = Inst.getOperand(2);
1827 return Error(IDLoc, "expected immediate operand kind");
1828 Imm = Opnd.getImm();
1829 if (Imm < 1 || Imm > 8)
1830 return Error(IDLoc, "immediate operand value out of range");
1833 Opnd = Inst.getOperand(1);
1835 return Error(IDLoc, "expected immediate operand kind");
1836 Imm = Opnd.getImm();
1837 if (Imm < -1 || Imm > 126)
1838 return Error(IDLoc, "immediate operand value out of range");
1840 case Mips::ADDIUR2_MM:
1841 Opnd = Inst.getOperand(2);
1843 return Error(IDLoc, "expected immediate operand kind");
1844 Imm = Opnd.getImm();
1845 if (!(Imm == 1 || Imm == -1 ||
1846 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1847 return Error(IDLoc, "immediate operand value out of range");
1849 case Mips::ADDIUR1SP_MM:
1850 Opnd = Inst.getOperand(1);
1852 return Error(IDLoc, "expected immediate operand kind");
1853 Imm = Opnd.getImm();
1854 if (OffsetToAlignment(Imm, 4LL))
1855 return Error(IDLoc, "misaligned immediate operand value");
1856 if (Imm < 0 || Imm > 255)
1857 return Error(IDLoc, "immediate operand value out of range");
1859 case Mips::ANDI16_MM:
1860 Opnd = Inst.getOperand(2);
1862 return Error(IDLoc, "expected immediate operand kind");
1863 Imm = Opnd.getImm();
1864 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1865 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1866 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1867 return Error(IDLoc, "immediate operand value out of range");
1869 case Mips::LBU16_MM:
1870 Opnd = Inst.getOperand(2);
1872 return Error(IDLoc, "expected immediate operand kind");
1873 Imm = Opnd.getImm();
1874 if (Imm < -1 || Imm > 14)
1875 return Error(IDLoc, "immediate operand value out of range");
1884 case Mips::SB16_MMR6:
1885 Opnd = Inst.getOperand(2);
1887 return Error(IDLoc, "expected immediate operand kind");
1888 Imm = Opnd.getImm();
1889 if (Imm < 0 || Imm > 15)
1890 return Error(IDLoc, "immediate operand value out of range");
1892 case Mips::LHU16_MM:
1894 case Mips::SH16_MMR6:
1895 Opnd = Inst.getOperand(2);
1897 return Error(IDLoc, "expected immediate operand kind");
1898 Imm = Opnd.getImm();
1899 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1900 return Error(IDLoc, "immediate operand value out of range");
1904 case Mips::SW16_MMR6:
1905 Opnd = Inst.getOperand(2);
1907 return Error(IDLoc, "expected immediate operand kind");
1908 Imm = Opnd.getImm();
1909 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1910 return Error(IDLoc, "immediate operand value out of range");
1912 case Mips::PREFX_MM:
1915 Opnd = Inst.getOperand(2);
1917 return Error(IDLoc, "expected immediate operand kind");
1918 Imm = Opnd.getImm();
1919 if (!isUInt<5>(Imm))
1920 return Error(IDLoc, "immediate operand value out of range");
1922 case Mips::ADDIUPC_MM:
1923 MCOperand Opnd = Inst.getOperand(1);
1925 return Error(IDLoc, "expected immediate operand kind");
1926 int Imm = Opnd.getImm();
1927 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1928 return Error(IDLoc, "immediate operand value out of range");
1933 MacroExpanderResultTy ExpandResult =
1934 tryExpandInstruction(Inst, IDLoc, Instructions);
1935 switch (ExpandResult) {
1937 Instructions.push_back(Inst);
1945 // If this instruction has a delay slot and .set reorder is active,
1946 // emit a NOP after it.
1947 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1948 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1950 if ((Inst.getOpcode() == Mips::JalOneReg ||
1951 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1952 isPicAndNotNxxAbi()) {
1953 if (IsCpRestoreSet) {
1954 // We need a NOP between the JALR and the LW:
1955 // If .set reorder has been used, we've already emitted a NOP.
1956 // If .set noreorder has been used, we need to emit a NOP at this point.
1957 if (!AssemblerOptions.back()->isReorder())
1958 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1960 // Load the $gp from the stack.
1961 SmallVector<MCInst, 3> LoadInsts;
1962 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1965 for (const MCInst &Inst : LoadInsts)
1966 Instructions.push_back(Inst);
1969 Warning(IDLoc, "no .cprestore used in PIC mode");
1975 MipsAsmParser::MacroExpanderResultTy
1976 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
1977 SmallVectorImpl<MCInst> &Instructions) {
1978 switch (Inst.getOpcode()) {
1980 return MER_NotAMacro;
1981 case Mips::LoadImm32:
1982 return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
1984 case Mips::LoadImm64:
1985 return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
1987 case Mips::LoadAddrImm32:
1988 case Mips::LoadAddrImm64:
1989 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1990 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1991 "expected immediate operand kind");
1993 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
1995 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1999 case Mips::LoadAddrReg32:
2000 case Mips::LoadAddrReg64:
2001 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2002 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2003 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2004 "expected immediate operand kind");
2006 return expandLoadAddress(Inst.getOperand(0).getReg(),
2007 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2008 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2012 case Mips::B_MM_Pseudo:
2013 case Mips::B_MMR6_Pseudo:
2014 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
2018 return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
2020 case Mips::JalOneReg:
2021 case Mips::JalTwoReg:
2022 return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
2026 return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2043 case Mips::BLTImmMacro:
2044 case Mips::BLEImmMacro:
2045 case Mips::BGEImmMacro:
2046 case Mips::BGTImmMacro:
2047 case Mips::BLTUImmMacro:
2048 case Mips::BLEUImmMacro:
2049 case Mips::BGEUImmMacro:
2050 case Mips::BGTUImmMacro:
2051 case Mips::BLTLImmMacro:
2052 case Mips::BLELImmMacro:
2053 case Mips::BGELImmMacro:
2054 case Mips::BGTLImmMacro:
2055 case Mips::BLTULImmMacro:
2056 case Mips::BLEULImmMacro:
2057 case Mips::BGEULImmMacro:
2058 case Mips::BGTULImmMacro:
2059 return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2061 case Mips::SDivMacro:
2062 return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2064 case Mips::DSDivMacro:
2065 return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2067 case Mips::UDivMacro:
2068 return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2070 case Mips::DUDivMacro:
2071 return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2074 return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2076 return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2078 return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2080 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2086 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2087 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2088 int64_t ImmValue = Inst.getOperand(2).getImm();
2089 if (isInt<16>(ImmValue))
2090 return MER_NotAMacro;
2091 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2094 return MER_NotAMacro;
2098 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2099 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2100 int64_t ImmValue = Inst.getOperand(2).getImm();
2101 if (isUInt<16>(ImmValue))
2102 return MER_NotAMacro;
2103 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2106 return MER_NotAMacro;
2109 return expandRotation(Inst, IDLoc, Instructions) ? MER_Fail
2113 return expandRotationImm(Inst, IDLoc, Instructions) ? MER_Fail
2117 return expandDRotation(Inst, IDLoc, Instructions) ? MER_Fail
2121 return expandDRotationImm(Inst, IDLoc, Instructions) ? MER_Fail
2126 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2127 SmallVectorImpl<MCInst> &Instructions) {
2128 // Create a JALR instruction which is going to replace the pseudo-JAL.
2130 JalrInst.setLoc(IDLoc);
2131 const MCOperand FirstRegOp = Inst.getOperand(0);
2132 const unsigned Opcode = Inst.getOpcode();
2134 if (Opcode == Mips::JalOneReg) {
2135 // jal $rs => jalr $rs
2136 if (IsCpRestoreSet && inMicroMipsMode()) {
2137 JalrInst.setOpcode(Mips::JALRS16_MM);
2138 JalrInst.addOperand(FirstRegOp);
2139 } else if (inMicroMipsMode()) {
2140 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2141 JalrInst.addOperand(FirstRegOp);
2143 JalrInst.setOpcode(Mips::JALR);
2144 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2145 JalrInst.addOperand(FirstRegOp);
2147 } else if (Opcode == Mips::JalTwoReg) {
2148 // jal $rd, $rs => jalr $rd, $rs
2149 if (IsCpRestoreSet && inMicroMipsMode())
2150 JalrInst.setOpcode(Mips::JALRS_MM);
2152 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2153 JalrInst.addOperand(FirstRegOp);
2154 const MCOperand SecondRegOp = Inst.getOperand(1);
2155 JalrInst.addOperand(SecondRegOp);
2157 Instructions.push_back(JalrInst);
2159 // If .set reorder is active and branch instruction has a delay slot,
2160 // emit a NOP after it.
2161 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2162 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2163 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2169 /// Can the value be represented by a unsigned N-bit value and a shift left?
2170 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2171 unsigned BitNum = findFirstSet(x);
2173 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2176 /// Load (or add) an immediate into a register.
2178 /// @param ImmValue The immediate to load.
2179 /// @param DstReg The register that will hold the immediate.
2180 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2181 /// for a simple initialization.
2182 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2183 /// @param IsAddress True if the immediate represents an address. False if it
2185 /// @param IDLoc Location of the immediate in the source file.
2186 /// @param Instructions The instructions emitted by this expansion.
2187 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2188 unsigned SrcReg, bool Is32BitImm,
2189 bool IsAddress, SMLoc IDLoc,
2190 SmallVectorImpl<MCInst> &Instructions) {
2191 if (!Is32BitImm && !isGP64bit()) {
2192 Error(IDLoc, "instruction requires a 64-bit architecture");
2197 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2198 // Sign extend up to 64-bit so that the predicates match the hardware
2199 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2201 ImmValue = SignExtend64<32>(ImmValue);
2203 Error(IDLoc, "instruction requires a 32-bit immediate");
2208 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2209 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2211 bool UseSrcReg = false;
2212 if (SrcReg != Mips::NoRegister)
2215 unsigned TmpReg = DstReg;
2216 if (UseSrcReg && (DstReg == SrcReg)) {
2217 // At this point we need AT to perform the expansions and we exit if it is
2219 unsigned ATReg = getATReg(IDLoc);
2225 if (isInt<16>(ImmValue)) {
2229 // This doesn't quite follow the usual ABI expectations for N32 but matches
2230 // traditional assembler behaviour. N32 would normally use addiu for both
2231 // integers and addresses.
2232 if (IsAddress && !Is32BitImm) {
2233 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2237 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2241 if (isUInt<16>(ImmValue)) {
2242 unsigned TmpReg = DstReg;
2243 if (SrcReg == DstReg) {
2244 TmpReg = getATReg(IDLoc);
2249 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2251 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2255 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2256 warnIfNoMacro(IDLoc);
2258 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2259 uint16_t Bits15To0 = ImmValue & 0xffff;
2261 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2262 // Traditional behaviour seems to special case this particular value. It's
2263 // not clear why other masks are handled differently.
2264 if (ImmValue == 0xffffffff) {
2265 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2266 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2268 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2272 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2274 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2275 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2277 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2279 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2283 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2285 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2287 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2291 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2293 Error(IDLoc, "instruction requires a 32-bit immediate");
2297 // Traditionally, these immediates are shifted as little as possible and as
2298 // such we align the most significant bit to bit 15 of our temporary.
2299 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2300 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2301 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2302 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2303 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2304 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2307 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2312 warnIfNoMacro(IDLoc);
2314 // The remaining case is packed with a sequence of dsll and ori with zeros
2315 // being omitted and any neighbouring dsll's being coalesced.
2316 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2318 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2319 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2320 IDLoc, Instructions))
2323 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2324 // skip it and defer the shift to the next chunk.
2325 unsigned ShiftCarriedForwards = 16;
2326 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2327 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2329 if (ImmChunk != 0) {
2330 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2332 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2333 ShiftCarriedForwards = 0;
2336 ShiftCarriedForwards += 16;
2338 ShiftCarriedForwards -= 16;
2340 // Finish any remaining shifts left by trailing zeros.
2341 if (ShiftCarriedForwards)
2342 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2346 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2351 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2352 SmallVectorImpl<MCInst> &Instructions) {
2353 const MCOperand &ImmOp = Inst.getOperand(1);
2354 assert(ImmOp.isImm() && "expected immediate operand kind");
2355 const MCOperand &DstRegOp = Inst.getOperand(0);
2356 assert(DstRegOp.isReg() && "expected register operand kind");
2358 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2359 Is32BitImm, false, IDLoc, Instructions))
2365 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2366 const MCOperand &Offset,
2367 bool Is32BitAddress, SMLoc IDLoc,
2368 SmallVectorImpl<MCInst> &Instructions) {
2369 // la can't produce a usable address when addresses are 64-bit.
2370 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2371 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2372 // We currently can't do this because we depend on the equality
2373 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2374 Error(IDLoc, "la used to load 64-bit address");
2375 // Continue as if we had 'dla' instead.
2376 Is32BitAddress = false;
2379 // dla requires 64-bit addresses.
2380 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2381 Error(IDLoc, "instruction requires a 64-bit architecture");
2385 if (!Offset.isImm())
2386 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2387 Is32BitAddress, IDLoc, Instructions);
2389 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2390 IDLoc, Instructions);
2393 bool MipsAsmParser::loadAndAddSymbolAddress(
2394 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2395 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2396 warnIfNoMacro(IDLoc);
2398 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2399 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2400 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2401 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2402 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2404 bool UseSrcReg = SrcReg != Mips::NoRegister;
2406 // This is the 64-bit symbol address expansion.
2407 if (ABI.ArePtrs64bit() && isGP64bit()) {
2408 // We always need AT for the 64-bit expansion.
2409 // If it is not available we exit.
2410 unsigned ATReg = getATReg(IDLoc);
2414 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2415 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2416 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2417 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2419 if (UseSrcReg && (DstReg == SrcReg)) {
2420 // If $rs is the same as $rd:
2421 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2422 // daddiu $at, $at, %higher(sym)
2423 // dsll $at, $at, 16
2424 // daddiu $at, $at, %hi(sym)
2425 // dsll $at, $at, 16
2426 // daddiu $at, $at, %lo(sym)
2427 // daddu $rd, $at, $rd
2428 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2430 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2431 IDLoc, Instructions);
2432 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2433 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2435 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2436 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2438 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2443 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2444 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2445 // lui $at, %hi(sym)
2446 // daddiu $rd, $rd, %higher(sym)
2447 // daddiu $at, $at, %lo(sym)
2448 // dsll32 $rd, $rd, 0
2449 // daddu $rd, $rd, $at
2450 // (daddu $rd, $rd, $rs)
2451 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2453 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2455 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2456 IDLoc, Instructions);
2457 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2459 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2460 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2462 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2467 // And now, the 32-bit symbol address expansion:
2468 // If $rs is the same as $rd:
2469 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2470 // ori $at, $at, %lo(sym)
2471 // addu $rd, $at, $rd
2472 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2473 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2474 // ori $rd, $rd, %lo(sym)
2475 // (addu $rd, $rd, $rs)
2476 unsigned TmpReg = DstReg;
2477 if (UseSrcReg && (DstReg == SrcReg)) {
2478 // If $rs is the same as $rd, we need to use AT.
2479 // If it is not available we exit.
2480 unsigned ATReg = getATReg(IDLoc);
2486 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2487 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2491 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2493 assert(DstReg == TmpReg);
2498 bool MipsAsmParser::expandUncondBranchMMPseudo(
2499 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2500 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2501 "unexpected number of operands");
2503 MCOperand Offset = Inst.getOperand(0);
2504 if (Offset.isExpr()) {
2506 Inst.setOpcode(Mips::BEQ_MM);
2507 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2508 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2509 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2511 assert(Offset.isImm() && "expected immediate operand kind");
2512 if (isInt<11>(Offset.getImm())) {
2513 // If offset fits into 11 bits then this instruction becomes microMIPS
2514 // 16-bit unconditional branch instruction.
2515 if (inMicroMipsMode())
2516 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2518 if (!isInt<17>(Offset.getImm()))
2519 Error(IDLoc, "branch target out of range");
2520 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2521 Error(IDLoc, "branch to misaligned address");
2523 Inst.setOpcode(Mips::BEQ_MM);
2524 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2525 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2526 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2529 Instructions.push_back(Inst);
2531 // If .set reorder is active and branch instruction has a delay slot,
2532 // emit a NOP after it.
2533 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2534 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2535 createNop(true, IDLoc, Instructions);
2540 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2541 SmallVectorImpl<MCInst> &Instructions) {
2542 const MCOperand &DstRegOp = Inst.getOperand(0);
2543 assert(DstRegOp.isReg() && "expected register operand kind");
2545 const MCOperand &ImmOp = Inst.getOperand(1);
2546 assert(ImmOp.isImm() && "expected immediate operand kind");
2548 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2549 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2551 unsigned OpCode = 0;
2552 switch(Inst.getOpcode()) {
2560 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2564 int64_t ImmValue = ImmOp.getImm();
2566 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2569 warnIfNoMacro(IDLoc);
2571 unsigned ATReg = getATReg(IDLoc);
2575 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2576 IDLoc, Instructions))
2579 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2584 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2585 SmallVectorImpl<MCInst> &Instructions,
2586 bool isLoad, bool isImmOpnd) {
2587 unsigned ImmOffset, HiOffset, LoOffset;
2588 const MCExpr *ExprOffset;
2590 // 1st operand is either the source or destination register.
2591 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2592 unsigned RegOpNum = Inst.getOperand(0).getReg();
2593 // 2nd operand is the base register.
2594 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2595 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2596 // 3rd operand is either an immediate or expression.
2598 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2599 ImmOffset = Inst.getOperand(2).getImm();
2600 LoOffset = ImmOffset & 0x0000ffff;
2601 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2602 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2603 if (LoOffset & 0x8000)
2606 ExprOffset = Inst.getOperand(2).getExpr();
2607 // These are some of the types of expansions we perform here:
2608 // 1) lw $8, sym => lui $8, %hi(sym)
2609 // lw $8, %lo(sym)($8)
2610 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2612 // lw $8, %lo(offset)($9)
2613 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2615 // lw $8, %lo(offset)($at)
2616 // 4) sw $8, sym => lui $at, %hi(sym)
2617 // sw $8, %lo(sym)($at)
2618 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2620 // sw $8, %lo(offset)($at)
2621 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2622 // ldc1 $f0, %lo(sym)($at)
2624 // For load instructions we can use the destination register as a temporary
2625 // if base and dst are different (examples 1 and 2) and if the base register
2626 // is general purpose otherwise we must use $at (example 6) and error if it's
2627 // not available. For stores we must use $at (examples 4 and 5) because we
2628 // must not clobber the source register setting up the offset.
2629 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2630 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2631 unsigned RegClassIDOp0 =
2632 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2633 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2634 (RegClassIDOp0 == Mips::GPR64RegClassID);
2635 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2636 TmpRegNum = RegOpNum;
2638 // At this point we need AT to perform the expansions and we exit if it is
2640 TmpRegNum = getATReg(IDLoc);
2645 emitRX(Mips::LUi, TmpRegNum,
2646 isImmOpnd ? MCOperand::createImm(HiOffset)
2647 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2648 IDLoc, Instructions);
2649 // Add temp register to base.
2650 if (BaseRegNum != Mips::ZERO)
2651 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2652 // And finally, create original instruction with low part
2653 // of offset and new base.
2654 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2656 ? MCOperand::createImm(LoOffset)
2657 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2658 IDLoc, Instructions);
2662 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2663 SmallVectorImpl<MCInst> &Instructions) {
2664 unsigned OpNum = Inst.getNumOperands();
2665 unsigned Opcode = Inst.getOpcode();
2666 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2668 assert (Inst.getOperand(OpNum - 1).isImm() &&
2669 Inst.getOperand(OpNum - 2).isReg() &&
2670 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2672 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2673 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2674 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2675 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2676 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2677 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2678 // It can be implemented as SWM16 or LWM16 instruction.
2679 if (inMicroMipsMode() && hasMips32r6())
2680 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2682 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2685 Inst.setOpcode(NewOpcode);
2686 Instructions.push_back(Inst);
2690 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2691 SmallVectorImpl<MCInst> &Instructions) {
2692 bool EmittedNoMacroWarning = false;
2693 unsigned PseudoOpcode = Inst.getOpcode();
2694 unsigned SrcReg = Inst.getOperand(0).getReg();
2695 const MCOperand &TrgOp = Inst.getOperand(1);
2696 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2698 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2699 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2703 TrgReg = TrgOp.getReg();
2704 else if (TrgOp.isImm()) {
2705 warnIfNoMacro(IDLoc);
2706 EmittedNoMacroWarning = true;
2708 TrgReg = getATReg(IDLoc);
2712 switch(PseudoOpcode) {
2714 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2715 case Mips::BLTImmMacro:
2716 PseudoOpcode = Mips::BLT;
2718 case Mips::BLEImmMacro:
2719 PseudoOpcode = Mips::BLE;
2721 case Mips::BGEImmMacro:
2722 PseudoOpcode = Mips::BGE;
2724 case Mips::BGTImmMacro:
2725 PseudoOpcode = Mips::BGT;
2727 case Mips::BLTUImmMacro:
2728 PseudoOpcode = Mips::BLTU;
2730 case Mips::BLEUImmMacro:
2731 PseudoOpcode = Mips::BLEU;
2733 case Mips::BGEUImmMacro:
2734 PseudoOpcode = Mips::BGEU;
2736 case Mips::BGTUImmMacro:
2737 PseudoOpcode = Mips::BGTU;
2739 case Mips::BLTLImmMacro:
2740 PseudoOpcode = Mips::BLTL;
2742 case Mips::BLELImmMacro:
2743 PseudoOpcode = Mips::BLEL;
2745 case Mips::BGELImmMacro:
2746 PseudoOpcode = Mips::BGEL;
2748 case Mips::BGTLImmMacro:
2749 PseudoOpcode = Mips::BGTL;
2751 case Mips::BLTULImmMacro:
2752 PseudoOpcode = Mips::BLTUL;
2754 case Mips::BLEULImmMacro:
2755 PseudoOpcode = Mips::BLEUL;
2757 case Mips::BGEULImmMacro:
2758 PseudoOpcode = Mips::BGEUL;
2760 case Mips::BGTULImmMacro:
2761 PseudoOpcode = Mips::BGTUL;
2765 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2766 false, IDLoc, Instructions))
2770 switch (PseudoOpcode) {
2775 AcceptsEquality = false;
2776 ReverseOrderSLT = false;
2777 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2778 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2779 ZeroSrcOpcode = Mips::BGTZ;
2780 ZeroTrgOpcode = Mips::BLTZ;
2786 AcceptsEquality = true;
2787 ReverseOrderSLT = true;
2788 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2789 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2790 ZeroSrcOpcode = Mips::BGEZ;
2791 ZeroTrgOpcode = Mips::BLEZ;
2797 AcceptsEquality = true;
2798 ReverseOrderSLT = false;
2799 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2800 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2801 ZeroSrcOpcode = Mips::BLEZ;
2802 ZeroTrgOpcode = Mips::BGEZ;
2808 AcceptsEquality = false;
2809 ReverseOrderSLT = true;
2810 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2811 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2812 ZeroSrcOpcode = Mips::BLTZ;
2813 ZeroTrgOpcode = Mips::BGTZ;
2816 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2819 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2820 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2821 if (IsSrcRegZero && IsTrgRegZero) {
2822 // FIXME: All of these Opcode-specific if's are needed for compatibility
2823 // with GAS' behaviour. However, they may not generate the most efficient
2824 // code in some circumstances.
2825 if (PseudoOpcode == Mips::BLT) {
2826 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2830 if (PseudoOpcode == Mips::BLE) {
2831 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2833 Warning(IDLoc, "branch is always taken");
2836 if (PseudoOpcode == Mips::BGE) {
2837 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2839 Warning(IDLoc, "branch is always taken");
2842 if (PseudoOpcode == Mips::BGT) {
2843 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2847 if (PseudoOpcode == Mips::BGTU) {
2848 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2849 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2852 if (AcceptsEquality) {
2853 // If both registers are $0 and the pseudo-branch accepts equality, it
2854 // will always be taken, so we emit an unconditional branch.
2855 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2856 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2857 Warning(IDLoc, "branch is always taken");
2860 // If both registers are $0 and the pseudo-branch does not accept
2861 // equality, it will never be taken, so we don't have to emit anything.
2864 if (IsSrcRegZero || IsTrgRegZero) {
2865 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2866 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2867 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2868 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2869 // the pseudo-branch will never be taken, so we don't emit anything.
2870 // This only applies to unsigned pseudo-branches.
2873 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2874 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2875 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2876 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2877 // the pseudo-branch will always be taken, so we emit an unconditional
2879 // This only applies to unsigned pseudo-branches.
2880 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2881 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2882 Warning(IDLoc, "branch is always taken");
2886 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2887 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2888 // the pseudo-branch will be taken only when the non-zero register is
2889 // different from 0, so we emit a BNEZ.
2891 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2892 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2893 // the pseudo-branch will be taken only when the non-zero register is
2894 // equal to 0, so we emit a BEQZ.
2896 // Because only BLEU and BGEU branch on equality, we can use the
2897 // AcceptsEquality variable to decide when to emit the BEQZ.
2898 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2899 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2900 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2903 // If we have a signed pseudo-branch and one of the registers is $0,
2904 // we can use an appropriate compare-to-zero branch. We select which one
2905 // to use in the switch statement above.
2906 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2907 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2908 IDLoc, Instructions);
2912 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2913 // expansions. If it is not available, we return.
2914 unsigned ATRegNum = getATReg(IDLoc);
2918 if (!EmittedNoMacroWarning)
2919 warnIfNoMacro(IDLoc);
2921 // SLT fits well with 2 of our 4 pseudo-branches:
2922 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2923 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2924 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2925 // This is accomplished by using a BNEZ with the result of the SLT.
2927 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2928 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2929 // Because only BGE and BLE branch on equality, we can use the
2930 // AcceptsEquality variable to decide when to emit the BEQZ.
2931 // Note that the order of the SLT arguments doesn't change between
2934 // The same applies to the unsigned variants, except that SLTu is used
2936 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2937 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2938 IDLoc, Instructions);
2940 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2941 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2942 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2947 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2948 SmallVectorImpl<MCInst> &Instructions,
2949 const bool IsMips64, const bool Signed) {
2950 if (hasMips32r6()) {
2951 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2955 warnIfNoMacro(IDLoc);
2957 const MCOperand &RsRegOp = Inst.getOperand(0);
2958 assert(RsRegOp.isReg() && "expected register operand kind");
2959 unsigned RsReg = RsRegOp.getReg();
2961 const MCOperand &RtRegOp = Inst.getOperand(1);
2962 assert(RtRegOp.isReg() && "expected register operand kind");
2963 unsigned RtReg = RtRegOp.getReg();
2968 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2969 ZeroReg = Mips::ZERO_64;
2971 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2972 ZeroReg = Mips::ZERO;
2975 bool UseTraps = useTraps();
2977 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2978 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2979 Warning(IDLoc, "dividing zero by zero");
2981 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2983 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2987 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2991 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2996 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2997 Warning(IDLoc, "division by zero");
3000 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
3004 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
3009 // FIXME: The values for these two BranchTarget variables may be different in
3010 // micromips. These magic numbers need to be removed.
3011 unsigned BranchTargetNoTraps;
3012 unsigned BranchTarget;
3015 BranchTarget = IsMips64 ? 12 : 8;
3016 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
3018 BranchTarget = IsMips64 ? 20 : 16;
3019 BranchTargetNoTraps = 8;
3020 // Branch to the li instruction.
3021 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
3025 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
3028 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
3031 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3035 unsigned ATReg = getATReg(IDLoc);
3039 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
3041 // Branch to the mflo instruction.
3042 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3043 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
3044 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
3046 // Branch to the mflo instruction.
3047 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3048 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
3052 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
3054 // Branch to the mflo instruction.
3055 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
3056 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
3057 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
3059 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3063 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3064 SmallVectorImpl<MCInst> &Instructions) {
3065 if (hasMips32r6() || hasMips64r6()) {
3066 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3070 warnIfNoMacro(IDLoc);
3072 const MCOperand &DstRegOp = Inst.getOperand(0);
3073 assert(DstRegOp.isReg() && "expected register operand kind");
3075 const MCOperand &SrcRegOp = Inst.getOperand(1);
3076 assert(SrcRegOp.isReg() && "expected register operand kind");
3078 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3079 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3081 unsigned DstReg = DstRegOp.getReg();
3082 unsigned SrcReg = SrcRegOp.getReg();
3083 int64_t OffsetValue = OffsetImmOp.getImm();
3085 // NOTE: We always need AT for ULHU, as it is always used as the source
3086 // register for one of the LBu's.
3087 unsigned ATReg = getATReg(IDLoc);
3091 // When the value of offset+1 does not fit in 16 bits, we have to load the
3092 // offset in AT, (D)ADDu the original source register (if there was one), and
3093 // then use AT as the source register for the 2 generated LBu's.
3094 bool LoadedOffsetInAT = false;
3095 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3096 LoadedOffsetInAT = true;
3098 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3099 true, IDLoc, Instructions))
3102 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3103 // because it will make our output more similar to GAS'. For example,
3104 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3105 // instead of just an "ori $1, $9, 32768".
3106 // NOTE: If there is no source register specified in the ULHU, the parser
3107 // will interpret it as $0.
3108 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3109 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3112 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3113 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3114 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3116 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3118 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3119 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3121 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3122 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3125 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3127 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3128 FirstLbuOffset, IDLoc, Instructions);
3130 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3133 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3135 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3140 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3141 SmallVectorImpl<MCInst> &Instructions) {
3142 if (hasMips32r6() || hasMips64r6()) {
3143 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3147 const MCOperand &DstRegOp = Inst.getOperand(0);
3148 assert(DstRegOp.isReg() && "expected register operand kind");
3150 const MCOperand &SrcRegOp = Inst.getOperand(1);
3151 assert(SrcRegOp.isReg() && "expected register operand kind");
3153 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3154 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3156 unsigned SrcReg = SrcRegOp.getReg();
3157 int64_t OffsetValue = OffsetImmOp.getImm();
3160 // When the value of offset+3 does not fit in 16 bits, we have to load the
3161 // offset in AT, (D)ADDu the original source register (if there was one), and
3162 // then use AT as the source register for the generated LWL and LWR.
3163 bool LoadedOffsetInAT = false;
3164 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3165 ATReg = getATReg(IDLoc);
3168 LoadedOffsetInAT = true;
3170 warnIfNoMacro(IDLoc);
3172 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3173 true, IDLoc, Instructions))
3176 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3177 // because it will make our output more similar to GAS'. For example,
3178 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3179 // instead of just an "ori $1, $9, 32768".
3180 // NOTE: If there is no source register specified in the ULW, the parser
3181 // will interpret it as $0.
3182 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3183 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3186 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3187 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3189 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3190 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3192 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3193 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3196 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3199 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3205 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3206 SmallVectorImpl<MCInst> &Instructions) {
3208 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3209 assert (Inst.getOperand(0).isReg() &&
3210 Inst.getOperand(1).isReg() &&
3211 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3213 unsigned ATReg = Mips::NoRegister;
3214 unsigned FinalDstReg = Mips::NoRegister;
3215 unsigned DstReg = Inst.getOperand(0).getReg();
3216 unsigned SrcReg = Inst.getOperand(1).getReg();
3217 int64_t ImmValue = Inst.getOperand(2).getImm();
3219 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3221 unsigned FinalOpcode = Inst.getOpcode();
3223 if (DstReg == SrcReg) {
3224 ATReg = getATReg(Inst.getLoc());
3227 FinalDstReg = DstReg;
3231 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3232 switch (FinalOpcode) {
3234 llvm_unreachable("unimplemented expansion");
3236 FinalOpcode = Mips::ADD;
3239 FinalOpcode = Mips::ADDu;
3242 FinalOpcode = Mips::AND;
3244 case (Mips::NORImm):
3245 FinalOpcode = Mips::NOR;
3248 FinalOpcode = Mips::OR;
3251 FinalOpcode = Mips::SLT;
3254 FinalOpcode = Mips::SLTu;
3257 FinalOpcode = Mips::XOR;
3261 if (FinalDstReg == Mips::NoRegister)
3262 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3264 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3271 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc,
3272 SmallVectorImpl<MCInst> &Instructions) {
3273 unsigned ATReg = Mips::NoRegister;
3274 unsigned DReg = Inst.getOperand(0).getReg();
3275 unsigned SReg = Inst.getOperand(1).getReg();
3276 unsigned TReg = Inst.getOperand(2).getReg();
3277 unsigned TmpReg = DReg;
3279 unsigned FirstShift = Mips::NOP;
3280 unsigned SecondShift = Mips::NOP;
3282 if (hasMips32r2()) {
3285 TmpReg = getATReg(Inst.getLoc());
3290 if (Inst.getOpcode() == Mips::ROL) {
3291 emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3292 emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Instructions);
3296 if (Inst.getOpcode() == Mips::ROR) {
3297 emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3306 switch (Inst.getOpcode()) {
3308 llvm_unreachable("unexpected instruction opcode");
3310 FirstShift = Mips::SRLV;
3311 SecondShift = Mips::SLLV;
3314 FirstShift = Mips::SLLV;
3315 SecondShift = Mips::SRLV;
3319 ATReg = getATReg(Inst.getLoc());
3323 emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3324 emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Instructions);
3325 emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3326 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3334 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3335 SmallVectorImpl<MCInst> &Instructions) {
3337 unsigned ATReg = Mips::NoRegister;
3338 unsigned DReg = Inst.getOperand(0).getReg();
3339 unsigned SReg = Inst.getOperand(1).getReg();
3340 int64_t ImmValue = Inst.getOperand(2).getImm();
3342 unsigned FirstShift = Mips::NOP;
3343 unsigned SecondShift = Mips::NOP;
3345 if (hasMips32r2()) {
3347 if (Inst.getOpcode() == Mips::ROLImm) {
3348 uint64_t MaxShift = 32;
3349 uint64_t ShiftValue = ImmValue;
3351 ShiftValue = MaxShift - ImmValue;
3352 emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), Instructions);
3356 if (Inst.getOpcode() == Mips::RORImm) {
3357 emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), Instructions);
3366 if (ImmValue == 0) {
3367 emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), Instructions);
3371 switch (Inst.getOpcode()) {
3373 llvm_unreachable("unexpected instruction opcode");
3375 FirstShift = Mips::SLL;
3376 SecondShift = Mips::SRL;
3379 FirstShift = Mips::SRL;
3380 SecondShift = Mips::SLL;
3384 ATReg = getATReg(Inst.getLoc());
3388 emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), Instructions);
3389 emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), Instructions);
3390 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3398 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc,
3399 SmallVectorImpl<MCInst> &Instructions) {
3401 unsigned ATReg = Mips::NoRegister;
3402 unsigned DReg = Inst.getOperand(0).getReg();
3403 unsigned SReg = Inst.getOperand(1).getReg();
3404 unsigned TReg = Inst.getOperand(2).getReg();
3405 unsigned TmpReg = DReg;
3407 unsigned FirstShift = Mips::NOP;
3408 unsigned SecondShift = Mips::NOP;
3410 if (hasMips64r2()) {
3412 if (TmpReg == SReg) {
3413 TmpReg = getATReg(Inst.getLoc());
3418 if (Inst.getOpcode() == Mips::DROL) {
3419 emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3420 emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Instructions);
3424 if (Inst.getOpcode() == Mips::DROR) {
3425 emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3434 switch (Inst.getOpcode()) {
3436 llvm_unreachable("unexpected instruction opcode");
3438 FirstShift = Mips::DSRLV;
3439 SecondShift = Mips::DSLLV;
3442 FirstShift = Mips::DSLLV;
3443 SecondShift = Mips::DSRLV;
3447 ATReg = getATReg(Inst.getLoc());
3451 emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3452 emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Instructions);
3453 emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3454 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3462 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
3463 SmallVectorImpl<MCInst> &Instructions) {
3465 unsigned ATReg = Mips::NoRegister;
3466 unsigned DReg = Inst.getOperand(0).getReg();
3467 unsigned SReg = Inst.getOperand(1).getReg();
3468 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
3470 unsigned FirstShift = Mips::NOP;
3471 unsigned SecondShift = Mips::NOP;
3475 if (hasMips64r2()) {
3477 unsigned FinalOpcode = Mips::NOP;
3479 FinalOpcode = Mips::DROTR;
3480 else if (ImmValue % 32 == 0)
3481 FinalOpcode = Mips::DROTR32;
3482 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3483 if (Inst.getOpcode() == Mips::DROLImm)
3484 FinalOpcode = Mips::DROTR32;
3486 FinalOpcode = Mips::DROTR;
3487 } else if (ImmValue >= 33) {
3488 if (Inst.getOpcode() == Mips::DROLImm)
3489 FinalOpcode = Mips::DROTR;
3491 FinalOpcode = Mips::DROTR32;
3494 uint64_t ShiftValue = ImmValue % 32;
3495 if (Inst.getOpcode() == Mips::DROLImm)
3496 ShiftValue = (32 - ImmValue % 32) % 32;
3498 emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), Instructions);
3505 if (ImmValue == 0) {
3506 emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), Instructions);
3510 switch (Inst.getOpcode()) {
3512 llvm_unreachable("unexpected instruction opcode");
3514 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3515 FirstShift = Mips::DSLL;
3516 SecondShift = Mips::DSRL32;
3518 if (ImmValue == 32) {
3519 FirstShift = Mips::DSLL32;
3520 SecondShift = Mips::DSRL32;
3522 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3523 FirstShift = Mips::DSLL32;
3524 SecondShift = Mips::DSRL;
3528 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3529 FirstShift = Mips::DSRL;
3530 SecondShift = Mips::DSLL32;
3532 if (ImmValue == 32) {
3533 FirstShift = Mips::DSRL32;
3534 SecondShift = Mips::DSLL32;
3536 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3537 FirstShift = Mips::DSRL32;
3538 SecondShift = Mips::DSLL;
3543 ATReg = getATReg(Inst.getLoc());
3547 emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), Instructions);
3548 emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32, Inst.getLoc(), Instructions);
3549 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3557 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3558 SmallVectorImpl<MCInst> &Instructions) {
3559 if (hasShortDelaySlot)
3560 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3562 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3565 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3566 unsigned TrgReg, bool Is64Bit,
3567 SmallVectorImpl<MCInst> &Instructions) {
3568 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3572 void MipsAsmParser::createCpRestoreMemOp(
3573 bool IsLoad, int StackOffset, SMLoc IDLoc,
3574 SmallVectorImpl<MCInst> &Instructions) {
3575 // If the offset can not fit into 16 bits, we need to expand.
3576 if (!isInt<16>(StackOffset)) {
3578 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3579 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3580 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3581 MemInst.addOperand(MCOperand::createImm(StackOffset));
3582 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3586 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3590 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3591 // As described by the Mips32r2 spec, the registers Rd and Rs for
3592 // jalr.hb must be different.
3593 unsigned Opcode = Inst.getOpcode();
3595 if (Opcode == Mips::JALR_HB &&
3596 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3597 return Match_RequiresDifferentSrcAndDst;
3599 return Match_Success;
3602 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3603 uint64_t ErrorInfo) {
3604 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3605 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3606 if (ErrorLoc == SMLoc())
3613 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3614 OperandVector &Operands,
3616 uint64_t &ErrorInfo,
3617 bool MatchingInlineAsm) {
3620 SmallVector<MCInst, 8> Instructions;
3621 unsigned MatchResult =
3622 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3624 switch (MatchResult) {
3625 case Match_Success: {
3626 if (processInstruction(Inst, IDLoc, Instructions))
3628 for (unsigned i = 0; i < Instructions.size(); i++)
3629 Out.EmitInstruction(Instructions[i], getSTI());
3632 case Match_MissingFeature:
3633 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3635 case Match_InvalidOperand: {
3636 SMLoc ErrorLoc = IDLoc;
3637 if (ErrorInfo != ~0ULL) {
3638 if (ErrorInfo >= Operands.size())
3639 return Error(IDLoc, "too few operands for instruction");
3641 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3642 if (ErrorLoc == SMLoc())
3646 return Error(ErrorLoc, "invalid operand for instruction");
3648 case Match_MnemonicFail:
3649 return Error(IDLoc, "invalid instruction");
3650 case Match_RequiresDifferentSrcAndDst:
3651 return Error(IDLoc, "source and destination must be different");
3653 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3655 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3656 "expected 1-bit unsigned immediate");
3658 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3659 "expected 2-bit unsigned immediate");
3661 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3662 "expected immediate in range 1 .. 4");
3664 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3665 "expected 3-bit unsigned immediate");
3667 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3668 "expected 4-bit unsigned immediate");
3671 llvm_unreachable("Implement any new match types added!");
3674 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3675 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3676 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3677 ") without \".set noat\"");
3680 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3681 if (!AssemblerOptions.back()->isMacro())
3682 Warning(Loc, "macro instruction expanded into multiple instructions");
3686 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3687 SMRange Range, bool ShowColors) {
3688 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3689 Range, SMFixIt(Range, FixMsg),
3693 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3696 CC = StringSwitch<unsigned>(Name)
3732 if (!(isABI_N32() || isABI_N64()))
3735 if (12 <= CC && CC <= 15) {
3736 // Name is one of t4-t7
3737 AsmToken RegTok = getLexer().peekTok();
3738 SMRange RegRange = RegTok.getLocRange();
3740 StringRef FixedName = StringSwitch<StringRef>(Name)
3746 assert(FixedName != "" && "Register name is not one of t4-t7.");
3748 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3749 "Did you mean $" + FixedName + "?", RegRange);
3752 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3753 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3754 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3755 if (8 <= CC && CC <= 11)
3759 CC = StringSwitch<unsigned>(Name)
3771 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3774 CC = StringSwitch<unsigned>(Name)
3775 .Case("hwr_cpunum", 0)
3776 .Case("hwr_synci_step", 1)
3778 .Case("hwr_ccres", 3)
3779 .Case("hwr_ulr", 29)
3785 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3787 if (Name[0] == 'f') {
3788 StringRef NumString = Name.substr(1);
3790 if (NumString.getAsInteger(10, IntVal))
3791 return -1; // This is not an integer.
3792 if (IntVal > 31) // Maximum index for fpu register.
3799 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3801 if (Name.startswith("fcc")) {
3802 StringRef NumString = Name.substr(3);
3804 if (NumString.getAsInteger(10, IntVal))
3805 return -1; // This is not an integer.
3806 if (IntVal > 7) // There are only 8 fcc registers.
3813 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3815 if (Name.startswith("ac")) {
3816 StringRef NumString = Name.substr(2);
3818 if (NumString.getAsInteger(10, IntVal))
3819 return -1; // This is not an integer.
3820 if (IntVal > 3) // There are only 3 acc registers.
3827 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3830 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3839 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3842 CC = StringSwitch<unsigned>(Name)
3845 .Case("msaaccess", 2)
3847 .Case("msamodify", 4)
3848 .Case("msarequest", 5)
3850 .Case("msaunmap", 7)
3856 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3857 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3859 reportParseError(Loc,
3860 "pseudo-instruction requires $at, which is not available");
3863 unsigned AT = getReg(
3864 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3868 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3869 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3872 unsigned MipsAsmParser::getGPR(int RegNo) {
3873 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3877 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3879 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3882 return getReg(RegClass, RegNum);
3885 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3886 MCAsmParser &Parser = getParser();
3887 DEBUG(dbgs() << "parseOperand\n");
3889 // Check if the current operand has a custom associated parser, if so, try to
3890 // custom parse the operand, or fallback to the general approach.
3891 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3892 if (ResTy == MatchOperand_Success)
3894 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3895 // there was a match, but an error occurred, in which case, just return that
3896 // the operand parsing failed.
3897 if (ResTy == MatchOperand_ParseFail)
3900 DEBUG(dbgs() << ".. Generic Parser\n");
3902 switch (getLexer().getKind()) {
3904 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3906 case AsmToken::Dollar: {
3907 // Parse the register.
3908 SMLoc S = Parser.getTok().getLoc();
3910 // Almost all registers have been parsed by custom parsers. There is only
3911 // one exception to this. $zero (and it's alias $0) will reach this point
3912 // for div, divu, and similar instructions because it is not an operand
3913 // to the instruction definition but an explicit register. Special case
3914 // this situation for now.
3915 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3918 // Maybe it is a symbol reference.
3919 StringRef Identifier;
3920 if (Parser.parseIdentifier(Identifier))
3923 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3924 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3925 // Otherwise create a symbol reference.
3927 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3929 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3932 // Else drop to expression parsing.
3933 case AsmToken::LParen:
3934 case AsmToken::Minus:
3935 case AsmToken::Plus:
3936 case AsmToken::Integer:
3937 case AsmToken::Tilde:
3938 case AsmToken::String: {
3939 DEBUG(dbgs() << ".. generic integer\n");
3940 OperandMatchResultTy ResTy = parseImm(Operands);
3941 return ResTy != MatchOperand_Success;
3943 case AsmToken::Percent: {
3944 // It is a symbol reference or constant expression.
3945 const MCExpr *IdVal;
3946 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3947 if (parseRelocOperand(IdVal))
3950 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3952 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3954 } // case AsmToken::Percent
3955 } // switch(getLexer().getKind())
3959 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3960 StringRef RelocStr) {
3962 // Check the type of the expression.
3963 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3964 // It's a constant, evaluate reloc value.
3966 switch (getVariantKind(RelocStr)) {
3967 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3968 // Get the 1st 16-bits.
3969 Val = MCE->getValue() & 0xffff;
3971 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3972 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3973 // 16 bits being negative.
3974 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3976 case MCSymbolRefExpr::VK_Mips_HIGHER:
3977 // Get the 3rd 16-bits.
3978 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3980 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3981 // Get the 4th 16-bits.
3982 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3985 report_fatal_error("unsupported reloc value");
3987 return MCConstantExpr::create(Val, getContext());
3990 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3991 // It's a symbol, create a symbolic expression from the symbol.
3992 const MCSymbol *Symbol = &MSRE->getSymbol();
3993 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3994 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3998 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3999 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
4001 // Try to create target expression.
4002 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
4003 return MipsMCExpr::create(VK, Expr, getContext());
4005 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
4006 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
4007 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
4011 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
4012 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
4013 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
4016 // Just return the original expression.
4020 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
4022 switch (Expr->getKind()) {
4023 case MCExpr::Constant:
4025 case MCExpr::SymbolRef:
4026 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
4027 case MCExpr::Binary:
4028 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4029 if (!isEvaluated(BE->getLHS()))
4031 return isEvaluated(BE->getRHS());
4034 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
4035 case MCExpr::Target:
4041 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
4042 MCAsmParser &Parser = getParser();
4043 Parser.Lex(); // Eat the % token.
4044 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
4045 if (Tok.isNot(AsmToken::Identifier))
4048 std::string Str = Tok.getIdentifier();
4050 Parser.Lex(); // Eat the identifier.
4051 // Now make an expression from the rest of the operand.
4052 const MCExpr *IdVal;
4055 if (getLexer().getKind() == AsmToken::LParen) {
4057 Parser.Lex(); // Eat the '(' token.
4058 if (getLexer().getKind() == AsmToken::Percent) {
4059 Parser.Lex(); // Eat the % token.
4060 const AsmToken &nextTok = Parser.getTok();
4061 if (nextTok.isNot(AsmToken::Identifier))
4064 Str += nextTok.getIdentifier();
4065 Parser.Lex(); // Eat the identifier.
4066 if (getLexer().getKind() != AsmToken::LParen)
4071 if (getParser().parseParenExpression(IdVal, EndLoc))
4074 while (getLexer().getKind() == AsmToken::RParen)
4075 Parser.Lex(); // Eat the ')' token.
4078 return true; // Parenthesis must follow the relocation operand.
4080 Res = evaluateRelocExpr(IdVal, Str);
4084 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
4086 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
4087 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4088 if (ResTy == MatchOperand_Success) {
4089 assert(Operands.size() == 1);
4090 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
4091 StartLoc = Operand.getStartLoc();
4092 EndLoc = Operand.getEndLoc();
4094 // AFAIK, we only support numeric registers and named GPR's in CFI
4096 // Don't worry about eating tokens before failing. Using an unrecognised
4097 // register is a parse error.
4098 if (Operand.isGPRAsmReg()) {
4099 // Resolve to GPR32 or GPR64 appropriately.
4100 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
4103 return (RegNo == (unsigned)-1);
4106 assert(Operands.size() == 0);
4107 return (RegNo == (unsigned)-1);
4110 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
4111 MCAsmParser &Parser = getParser();
4114 unsigned NumOfLParen = 0;
4116 while (getLexer().getKind() == AsmToken::LParen) {
4121 switch (getLexer().getKind()) {
4124 case AsmToken::Identifier:
4125 case AsmToken::LParen:
4126 case AsmToken::Integer:
4127 case AsmToken::Minus:
4128 case AsmToken::Plus:
4130 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
4132 Result = (getParser().parseExpression(Res));
4133 while (getLexer().getKind() == AsmToken::RParen)
4136 case AsmToken::Percent:
4137 Result = parseRelocOperand(Res);
4142 MipsAsmParser::OperandMatchResultTy
4143 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
4144 MCAsmParser &Parser = getParser();
4145 DEBUG(dbgs() << "parseMemOperand\n");
4146 const MCExpr *IdVal = nullptr;
4148 bool isParenExpr = false;
4149 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
4150 // First operand is the offset.
4151 S = Parser.getTok().getLoc();
4153 if (getLexer().getKind() == AsmToken::LParen) {
4158 if (getLexer().getKind() != AsmToken::Dollar) {
4159 if (parseMemOffset(IdVal, isParenExpr))
4160 return MatchOperand_ParseFail;
4162 const AsmToken &Tok = Parser.getTok(); // Get the next token.
4163 if (Tok.isNot(AsmToken::LParen)) {
4164 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
4165 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
4167 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4168 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4169 return MatchOperand_Success;
4171 if (Tok.is(AsmToken::EndOfStatement)) {
4173 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4175 // Zero register assumed, add a memory operand with ZERO as its base.
4176 // "Base" will be managed by k_Memory.
4177 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
4180 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
4181 return MatchOperand_Success;
4183 Error(Parser.getTok().getLoc(), "'(' expected");
4184 return MatchOperand_ParseFail;
4187 Parser.Lex(); // Eat the '(' token.
4190 Res = parseAnyRegister(Operands);
4191 if (Res != MatchOperand_Success)
4194 if (Parser.getTok().isNot(AsmToken::RParen)) {
4195 Error(Parser.getTok().getLoc(), "')' expected");
4196 return MatchOperand_ParseFail;
4199 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4201 Parser.Lex(); // Eat the ')' token.
4204 IdVal = MCConstantExpr::create(0, getContext());
4206 // Replace the register operand with the memory operand.
4207 std::unique_ptr<MipsOperand> op(
4208 static_cast<MipsOperand *>(Operands.back().release()));
4209 // Remove the register from the operands.
4210 // "op" will be managed by k_Memory.
4211 Operands.pop_back();
4212 // Add the memory operand.
4213 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
4215 if (IdVal->evaluateAsAbsolute(Imm))
4216 IdVal = MCConstantExpr::create(Imm, getContext());
4217 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
4218 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
4222 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
4223 return MatchOperand_Success;
4226 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
4227 MCAsmParser &Parser = getParser();
4228 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
4230 SMLoc S = Parser.getTok().getLoc();
4232 if (Sym->isVariable())
4233 Expr = Sym->getVariableValue();
4236 if (Expr->getKind() == MCExpr::SymbolRef) {
4237 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4238 StringRef DefSymbol = Ref->getSymbol().getName();
4239 if (DefSymbol.startswith("$")) {
4240 OperandMatchResultTy ResTy =
4241 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
4242 if (ResTy == MatchOperand_Success) {
4245 } else if (ResTy == MatchOperand_ParseFail)
4246 llvm_unreachable("Should never ParseFail");
4249 } else if (Expr->getKind() == MCExpr::Constant) {
4251 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
4253 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
4260 MipsAsmParser::OperandMatchResultTy
4261 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
4262 StringRef Identifier,
4264 int Index = matchCPURegisterName(Identifier);
4266 Operands.push_back(MipsOperand::createGPRReg(
4267 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4268 return MatchOperand_Success;
4271 Index = matchHWRegsRegisterName(Identifier);
4273 Operands.push_back(MipsOperand::createHWRegsReg(
4274 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4275 return MatchOperand_Success;
4278 Index = matchFPURegisterName(Identifier);
4280 Operands.push_back(MipsOperand::createFGRReg(
4281 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4282 return MatchOperand_Success;
4285 Index = matchFCCRegisterName(Identifier);
4287 Operands.push_back(MipsOperand::createFCCReg(
4288 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4289 return MatchOperand_Success;
4292 Index = matchACRegisterName(Identifier);
4294 Operands.push_back(MipsOperand::createACCReg(
4295 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4296 return MatchOperand_Success;
4299 Index = matchMSA128RegisterName(Identifier);
4301 Operands.push_back(MipsOperand::createMSA128Reg(
4302 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4303 return MatchOperand_Success;
4306 Index = matchMSA128CtrlRegisterName(Identifier);
4308 Operands.push_back(MipsOperand::createMSACtrlReg(
4309 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4310 return MatchOperand_Success;
4313 return MatchOperand_NoMatch;
4316 MipsAsmParser::OperandMatchResultTy
4317 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
4318 MCAsmParser &Parser = getParser();
4319 auto Token = Parser.getLexer().peekTok(false);
4321 if (Token.is(AsmToken::Identifier)) {
4322 DEBUG(dbgs() << ".. identifier\n");
4323 StringRef Identifier = Token.getIdentifier();
4324 OperandMatchResultTy ResTy =
4325 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4327 } else if (Token.is(AsmToken::Integer)) {
4328 DEBUG(dbgs() << ".. integer\n");
4329 Operands.push_back(MipsOperand::createNumericReg(
4330 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
4332 return MatchOperand_Success;
4335 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4337 return MatchOperand_NoMatch;
4340 MipsAsmParser::OperandMatchResultTy
4341 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4342 MCAsmParser &Parser = getParser();
4343 DEBUG(dbgs() << "parseAnyRegister\n");
4345 auto Token = Parser.getTok();
4347 SMLoc S = Token.getLoc();
4349 if (Token.isNot(AsmToken::Dollar)) {
4350 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4351 if (Token.is(AsmToken::Identifier)) {
4352 if (searchSymbolAlias(Operands))
4353 return MatchOperand_Success;
4355 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4356 return MatchOperand_NoMatch;
4358 DEBUG(dbgs() << ".. $\n");
4360 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4361 if (ResTy == MatchOperand_Success) {
4363 Parser.Lex(); // identifier
4368 MipsAsmParser::OperandMatchResultTy
4369 MipsAsmParser::parseImm(OperandVector &Operands) {
4370 MCAsmParser &Parser = getParser();
4371 switch (getLexer().getKind()) {
4373 return MatchOperand_NoMatch;
4374 case AsmToken::LParen:
4375 case AsmToken::Minus:
4376 case AsmToken::Plus:
4377 case AsmToken::Integer:
4378 case AsmToken::Tilde:
4379 case AsmToken::String:
4383 const MCExpr *IdVal;
4384 SMLoc S = Parser.getTok().getLoc();
4385 if (getParser().parseExpression(IdVal))
4386 return MatchOperand_ParseFail;
4388 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4389 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4390 return MatchOperand_Success;
4393 MipsAsmParser::OperandMatchResultTy
4394 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4395 MCAsmParser &Parser = getParser();
4396 DEBUG(dbgs() << "parseJumpTarget\n");
4398 SMLoc S = getLexer().getLoc();
4400 // Integers and expressions are acceptable
4401 OperandMatchResultTy ResTy = parseImm(Operands);
4402 if (ResTy != MatchOperand_NoMatch)
4405 // Registers are a valid target and have priority over symbols.
4406 ResTy = parseAnyRegister(Operands);
4407 if (ResTy != MatchOperand_NoMatch)
4410 const MCExpr *Expr = nullptr;
4411 if (Parser.parseExpression(Expr)) {
4412 // We have no way of knowing if a symbol was consumed so we must ParseFail
4413 return MatchOperand_ParseFail;
4416 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4417 return MatchOperand_Success;
4420 MipsAsmParser::OperandMatchResultTy
4421 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4422 MCAsmParser &Parser = getParser();
4423 const MCExpr *IdVal;
4424 // If the first token is '$' we may have register operand.
4425 if (Parser.getTok().is(AsmToken::Dollar))
4426 return MatchOperand_NoMatch;
4427 SMLoc S = Parser.getTok().getLoc();
4428 if (getParser().parseExpression(IdVal))
4429 return MatchOperand_ParseFail;
4430 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4431 assert(MCE && "Unexpected MCExpr type.");
4432 int64_t Val = MCE->getValue();
4433 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4434 Operands.push_back(MipsOperand::CreateImm(
4435 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4436 return MatchOperand_Success;
4439 MipsAsmParser::OperandMatchResultTy
4440 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4441 MCAsmParser &Parser = getParser();
4442 switch (getLexer().getKind()) {
4444 return MatchOperand_NoMatch;
4445 case AsmToken::LParen:
4446 case AsmToken::Plus:
4447 case AsmToken::Minus:
4448 case AsmToken::Integer:
4453 SMLoc S = Parser.getTok().getLoc();
4455 if (getParser().parseExpression(Expr))
4456 return MatchOperand_ParseFail;
4459 if (!Expr->evaluateAsAbsolute(Val)) {
4460 Error(S, "expected immediate value");
4461 return MatchOperand_ParseFail;
4464 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4465 // and because the CPU always adds one to the immediate field, the allowed
4466 // range becomes 1..4. We'll only check the range here and will deal
4467 // with the addition/subtraction when actually decoding/encoding
4469 if (Val < 1 || Val > 4) {
4470 Error(S, "immediate not in range (1..4)");
4471 return MatchOperand_ParseFail;
4475 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4476 return MatchOperand_Success;
4479 MipsAsmParser::OperandMatchResultTy
4480 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4481 MCAsmParser &Parser = getParser();
4482 SmallVector<unsigned, 10> Regs;
4484 unsigned PrevReg = Mips::NoRegister;
4485 bool RegRange = false;
4486 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4488 if (Parser.getTok().isNot(AsmToken::Dollar))
4489 return MatchOperand_ParseFail;
4491 SMLoc S = Parser.getTok().getLoc();
4492 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4493 SMLoc E = getLexer().getLoc();
4494 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4495 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4497 // Remove last register operand because registers from register range
4498 // should be inserted first.
4499 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4500 (!isGP64bit() && RegNo == Mips::RA)) {
4501 Regs.push_back(RegNo);
4503 unsigned TmpReg = PrevReg + 1;
4504 while (TmpReg <= RegNo) {
4505 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4506 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4508 Error(E, "invalid register operand");
4509 return MatchOperand_ParseFail;
4513 Regs.push_back(TmpReg++);
4519 if ((PrevReg == Mips::NoRegister) &&
4520 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
4521 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
4522 Error(E, "$16 or $31 expected");
4523 return MatchOperand_ParseFail;
4524 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
4525 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
4527 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
4528 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
4530 Error(E, "invalid register operand");
4531 return MatchOperand_ParseFail;
4532 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4533 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
4534 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
4536 Error(E, "consecutive register numbers expected");
4537 return MatchOperand_ParseFail;
4540 Regs.push_back(RegNo);
4543 if (Parser.getTok().is(AsmToken::Minus))
4546 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4547 !Parser.getTok().isNot(AsmToken::Comma)) {
4548 Error(E, "',' or '-' expected");
4549 return MatchOperand_ParseFail;
4552 Lex(); // Consume comma or minus
4553 if (Parser.getTok().isNot(AsmToken::Dollar))
4559 SMLoc E = Parser.getTok().getLoc();
4560 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4561 parseMemOperand(Operands);
4562 return MatchOperand_Success;
4565 MipsAsmParser::OperandMatchResultTy
4566 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4567 MCAsmParser &Parser = getParser();
4569 SMLoc S = Parser.getTok().getLoc();
4570 if (parseAnyRegister(Operands) != MatchOperand_Success)
4571 return MatchOperand_ParseFail;
4573 SMLoc E = Parser.getTok().getLoc();
4574 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4575 unsigned Reg = Op.getGPR32Reg();
4576 Operands.pop_back();
4577 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4578 return MatchOperand_Success;
4581 MipsAsmParser::OperandMatchResultTy
4582 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4583 MCAsmParser &Parser = getParser();
4584 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4585 SmallVector<unsigned, 10> Regs;
4587 if (Parser.getTok().isNot(AsmToken::Dollar))
4588 return MatchOperand_ParseFail;
4590 SMLoc S = Parser.getTok().getLoc();
4592 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4593 return MatchOperand_ParseFail;
4595 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4596 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4597 Regs.push_back(RegNo);
4599 SMLoc E = Parser.getTok().getLoc();
4600 if (Parser.getTok().isNot(AsmToken::Comma)) {
4601 Error(E, "',' expected");
4602 return MatchOperand_ParseFail;
4608 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4609 return MatchOperand_ParseFail;
4611 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4612 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4613 Regs.push_back(RegNo);
4615 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4617 return MatchOperand_Success;
4620 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4622 MCSymbolRefExpr::VariantKind VK =
4623 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4624 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4625 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4626 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4627 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4628 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4629 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4630 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4631 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4632 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4633 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4634 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4635 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4636 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4637 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4638 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4639 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4640 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4641 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4642 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4643 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4644 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4645 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4646 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4647 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4648 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4649 .Default(MCSymbolRefExpr::VK_None);
4651 assert(VK != MCSymbolRefExpr::VK_None);
4656 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4658 /// ::= '(', register, ')'
4659 /// handle it before we iterate so we don't get tripped up by the lack of
4661 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4662 MCAsmParser &Parser = getParser();
4663 if (getLexer().is(AsmToken::LParen)) {
4665 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4667 if (parseOperand(Operands, Name)) {
4668 SMLoc Loc = getLexer().getLoc();
4669 Parser.eatToEndOfStatement();
4670 return Error(Loc, "unexpected token in argument list");
4672 if (Parser.getTok().isNot(AsmToken::RParen)) {
4673 SMLoc Loc = getLexer().getLoc();
4674 Parser.eatToEndOfStatement();
4675 return Error(Loc, "unexpected token, expected ')'");
4678 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4684 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4685 /// either one of these.
4686 /// ::= '[', register, ']'
4687 /// ::= '[', integer, ']'
4688 /// handle it before we iterate so we don't get tripped up by the lack of
4690 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4691 OperandVector &Operands) {
4692 MCAsmParser &Parser = getParser();
4693 if (getLexer().is(AsmToken::LBrac)) {
4695 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4697 if (parseOperand(Operands, Name)) {
4698 SMLoc Loc = getLexer().getLoc();
4699 Parser.eatToEndOfStatement();
4700 return Error(Loc, "unexpected token in argument list");
4702 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4703 SMLoc Loc = getLexer().getLoc();
4704 Parser.eatToEndOfStatement();
4705 return Error(Loc, "unexpected token, expected ']'");
4708 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4714 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4715 SMLoc NameLoc, OperandVector &Operands) {
4716 MCAsmParser &Parser = getParser();
4717 DEBUG(dbgs() << "ParseInstruction\n");
4719 // We have reached first instruction, module directive are now forbidden.
4720 getTargetStreamer().forbidModuleDirective();
4722 // Check if we have valid mnemonic
4723 if (!mnemonicIsValid(Name, 0)) {
4724 Parser.eatToEndOfStatement();
4725 return Error(NameLoc, "unknown instruction");
4727 // First operand in MCInst is instruction mnemonic.
4728 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4730 // Read the remaining operands.
4731 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4732 // Read the first operand.
4733 if (parseOperand(Operands, Name)) {
4734 SMLoc Loc = getLexer().getLoc();
4735 Parser.eatToEndOfStatement();
4736 return Error(Loc, "unexpected token in argument list");
4738 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4740 // AFAIK, parenthesis suffixes are never on the first operand
4742 while (getLexer().is(AsmToken::Comma)) {
4743 Parser.Lex(); // Eat the comma.
4744 // Parse and remember the operand.
4745 if (parseOperand(Operands, Name)) {
4746 SMLoc Loc = getLexer().getLoc();
4747 Parser.eatToEndOfStatement();
4748 return Error(Loc, "unexpected token in argument list");
4750 // Parse bracket and parenthesis suffixes before we iterate
4751 if (getLexer().is(AsmToken::LBrac)) {
4752 if (parseBracketSuffix(Name, Operands))
4754 } else if (getLexer().is(AsmToken::LParen) &&
4755 parseParenSuffix(Name, Operands))
4759 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4760 SMLoc Loc = getLexer().getLoc();
4761 Parser.eatToEndOfStatement();
4762 return Error(Loc, "unexpected token in argument list");
4764 Parser.Lex(); // Consume the EndOfStatement.
4768 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4769 MCAsmParser &Parser = getParser();
4770 SMLoc Loc = getLexer().getLoc();
4771 Parser.eatToEndOfStatement();
4772 return Error(Loc, ErrorMsg);
4775 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4776 return Error(Loc, ErrorMsg);
4779 bool MipsAsmParser::parseSetNoAtDirective() {
4780 MCAsmParser &Parser = getParser();
4781 // Line should look like: ".set noat".
4783 // Set the $at register to $0.
4784 AssemblerOptions.back()->setATRegIndex(0);
4786 Parser.Lex(); // Eat "noat".
4788 // If this is not the end of the statement, report an error.
4789 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4790 reportParseError("unexpected token, expected end of statement");
4794 getTargetStreamer().emitDirectiveSetNoAt();
4795 Parser.Lex(); // Consume the EndOfStatement.
4799 bool MipsAsmParser::parseSetAtDirective() {
4800 // Line can be: ".set at", which sets $at to $1
4801 // or ".set at=$reg", which sets $at to $reg.
4802 MCAsmParser &Parser = getParser();
4803 Parser.Lex(); // Eat "at".
4805 if (getLexer().is(AsmToken::EndOfStatement)) {
4806 // No register was specified, so we set $at to $1.
4807 AssemblerOptions.back()->setATRegIndex(1);
4809 getTargetStreamer().emitDirectiveSetAt();
4810 Parser.Lex(); // Consume the EndOfStatement.
4814 if (getLexer().isNot(AsmToken::Equal)) {
4815 reportParseError("unexpected token, expected equals sign");
4818 Parser.Lex(); // Eat "=".
4820 if (getLexer().isNot(AsmToken::Dollar)) {
4821 if (getLexer().is(AsmToken::EndOfStatement)) {
4822 reportParseError("no register specified");
4825 reportParseError("unexpected token, expected dollar sign '$'");
4829 Parser.Lex(); // Eat "$".
4831 // Find out what "reg" is.
4833 const AsmToken &Reg = Parser.getTok();
4834 if (Reg.is(AsmToken::Identifier)) {
4835 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4836 } else if (Reg.is(AsmToken::Integer)) {
4837 AtRegNo = Reg.getIntVal();
4839 reportParseError("unexpected token, expected identifier or integer");
4843 // Check if $reg is a valid register. If it is, set $at to $reg.
4844 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4845 reportParseError("invalid register");
4848 Parser.Lex(); // Eat "reg".
4850 // If this is not the end of the statement, report an error.
4851 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4852 reportParseError("unexpected token, expected end of statement");
4856 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4858 Parser.Lex(); // Consume the EndOfStatement.
4862 bool MipsAsmParser::parseSetReorderDirective() {
4863 MCAsmParser &Parser = getParser();
4865 // If this is not the end of the statement, report an error.
4866 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4867 reportParseError("unexpected token, expected end of statement");
4870 AssemblerOptions.back()->setReorder();
4871 getTargetStreamer().emitDirectiveSetReorder();
4872 Parser.Lex(); // Consume the EndOfStatement.
4876 bool MipsAsmParser::parseSetNoReorderDirective() {
4877 MCAsmParser &Parser = getParser();
4879 // If this is not the end of the statement, report an error.
4880 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4881 reportParseError("unexpected token, expected end of statement");
4884 AssemblerOptions.back()->setNoReorder();
4885 getTargetStreamer().emitDirectiveSetNoReorder();
4886 Parser.Lex(); // Consume the EndOfStatement.
4890 bool MipsAsmParser::parseSetMacroDirective() {
4891 MCAsmParser &Parser = getParser();
4893 // If this is not the end of the statement, report an error.
4894 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4895 reportParseError("unexpected token, expected end of statement");
4898 AssemblerOptions.back()->setMacro();
4899 getTargetStreamer().emitDirectiveSetMacro();
4900 Parser.Lex(); // Consume the EndOfStatement.
4904 bool MipsAsmParser::parseSetNoMacroDirective() {
4905 MCAsmParser &Parser = getParser();
4907 // If this is not the end of the statement, report an error.
4908 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4909 reportParseError("unexpected token, expected end of statement");
4912 if (AssemblerOptions.back()->isReorder()) {
4913 reportParseError("`noreorder' must be set before `nomacro'");
4916 AssemblerOptions.back()->setNoMacro();
4917 getTargetStreamer().emitDirectiveSetNoMacro();
4918 Parser.Lex(); // Consume the EndOfStatement.
4922 bool MipsAsmParser::parseSetMsaDirective() {
4923 MCAsmParser &Parser = getParser();
4926 // If this is not the end of the statement, report an error.
4927 if (getLexer().isNot(AsmToken::EndOfStatement))
4928 return reportParseError("unexpected token, expected end of statement");
4930 setFeatureBits(Mips::FeatureMSA, "msa");
4931 getTargetStreamer().emitDirectiveSetMsa();
4935 bool MipsAsmParser::parseSetNoMsaDirective() {
4936 MCAsmParser &Parser = getParser();
4939 // If this is not the end of the statement, report an error.
4940 if (getLexer().isNot(AsmToken::EndOfStatement))
4941 return reportParseError("unexpected token, expected end of statement");
4943 clearFeatureBits(Mips::FeatureMSA, "msa");
4944 getTargetStreamer().emitDirectiveSetNoMsa();
4948 bool MipsAsmParser::parseSetNoDspDirective() {
4949 MCAsmParser &Parser = getParser();
4950 Parser.Lex(); // Eat "nodsp".
4952 // If this is not the end of the statement, report an error.
4953 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4954 reportParseError("unexpected token, expected end of statement");
4958 clearFeatureBits(Mips::FeatureDSP, "dsp");
4959 getTargetStreamer().emitDirectiveSetNoDsp();
4963 bool MipsAsmParser::parseSetMips16Directive() {
4964 MCAsmParser &Parser = getParser();
4965 Parser.Lex(); // Eat "mips16".
4967 // If this is not the end of the statement, report an error.
4968 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4969 reportParseError("unexpected token, expected end of statement");
4973 setFeatureBits(Mips::FeatureMips16, "mips16");
4974 getTargetStreamer().emitDirectiveSetMips16();
4975 Parser.Lex(); // Consume the EndOfStatement.
4979 bool MipsAsmParser::parseSetNoMips16Directive() {
4980 MCAsmParser &Parser = getParser();
4981 Parser.Lex(); // Eat "nomips16".
4983 // If this is not the end of the statement, report an error.
4984 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4985 reportParseError("unexpected token, expected end of statement");
4989 clearFeatureBits(Mips::FeatureMips16, "mips16");
4990 getTargetStreamer().emitDirectiveSetNoMips16();
4991 Parser.Lex(); // Consume the EndOfStatement.
4995 bool MipsAsmParser::parseSetFpDirective() {
4996 MCAsmParser &Parser = getParser();
4997 MipsABIFlagsSection::FpABIKind FpAbiVal;
4998 // Line can be: .set fp=32
5001 Parser.Lex(); // Eat fp token
5002 AsmToken Tok = Parser.getTok();
5003 if (Tok.isNot(AsmToken::Equal)) {
5004 reportParseError("unexpected token, expected equals sign '='");
5007 Parser.Lex(); // Eat '=' token.
5008 Tok = Parser.getTok();
5010 if (!parseFpABIValue(FpAbiVal, ".set"))
5013 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5014 reportParseError("unexpected token, expected end of statement");
5017 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5018 Parser.Lex(); // Consume the EndOfStatement.
5022 bool MipsAsmParser::parseSetOddSPRegDirective() {
5023 MCAsmParser &Parser = getParser();
5025 Parser.Lex(); // Eat "oddspreg".
5026 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5027 reportParseError("unexpected token, expected end of statement");
5031 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5032 getTargetStreamer().emitDirectiveSetOddSPReg();
5036 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5037 MCAsmParser &Parser = getParser();
5039 Parser.Lex(); // Eat "nooddspreg".
5040 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5041 reportParseError("unexpected token, expected end of statement");
5045 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5046 getTargetStreamer().emitDirectiveSetNoOddSPReg();
5050 bool MipsAsmParser::parseSetPopDirective() {
5051 MCAsmParser &Parser = getParser();
5052 SMLoc Loc = getLexer().getLoc();
5055 if (getLexer().isNot(AsmToken::EndOfStatement))
5056 return reportParseError("unexpected token, expected end of statement");
5058 // Always keep an element on the options "stack" to prevent the user
5059 // from changing the initial options. This is how we remember them.
5060 if (AssemblerOptions.size() == 2)
5061 return reportParseError(Loc, ".set pop with no .set push");
5063 MCSubtargetInfo &STI = copySTI();
5064 AssemblerOptions.pop_back();
5065 setAvailableFeatures(
5066 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5067 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
5069 getTargetStreamer().emitDirectiveSetPop();
5073 bool MipsAsmParser::parseSetPushDirective() {
5074 MCAsmParser &Parser = getParser();
5076 if (getLexer().isNot(AsmToken::EndOfStatement))
5077 return reportParseError("unexpected token, expected end of statement");
5079 // Create a copy of the current assembler options environment and push it.
5080 AssemblerOptions.push_back(
5081 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5083 getTargetStreamer().emitDirectiveSetPush();
5087 bool MipsAsmParser::parseSetSoftFloatDirective() {
5088 MCAsmParser &Parser = getParser();
5090 if (getLexer().isNot(AsmToken::EndOfStatement))
5091 return reportParseError("unexpected token, expected end of statement");
5093 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5094 getTargetStreamer().emitDirectiveSetSoftFloat();
5098 bool MipsAsmParser::parseSetHardFloatDirective() {
5099 MCAsmParser &Parser = getParser();
5101 if (getLexer().isNot(AsmToken::EndOfStatement))
5102 return reportParseError("unexpected token, expected end of statement");
5104 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5105 getTargetStreamer().emitDirectiveSetHardFloat();
5109 bool MipsAsmParser::parseSetAssignment() {
5111 const MCExpr *Value;
5112 MCAsmParser &Parser = getParser();
5114 if (Parser.parseIdentifier(Name))
5115 reportParseError("expected identifier after .set");
5117 if (getLexer().isNot(AsmToken::Comma))
5118 return reportParseError("unexpected token, expected comma");
5121 if (Parser.parseExpression(Value))
5122 return reportParseError("expected valid expression after comma");
5124 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5125 Sym->setVariableValue(Value);
5130 bool MipsAsmParser::parseSetMips0Directive() {
5131 MCAsmParser &Parser = getParser();
5133 if (getLexer().isNot(AsmToken::EndOfStatement))
5134 return reportParseError("unexpected token, expected end of statement");
5136 // Reset assembler options to their initial values.
5137 MCSubtargetInfo &STI = copySTI();
5138 setAvailableFeatures(
5139 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
5140 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
5141 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
5143 getTargetStreamer().emitDirectiveSetMips0();
5147 bool MipsAsmParser::parseSetArchDirective() {
5148 MCAsmParser &Parser = getParser();
5150 if (getLexer().isNot(AsmToken::Equal))
5151 return reportParseError("unexpected token, expected equals sign");
5155 if (Parser.parseIdentifier(Arch))
5156 return reportParseError("expected arch identifier");
5158 StringRef ArchFeatureName =
5159 StringSwitch<StringRef>(Arch)
5160 .Case("mips1", "mips1")
5161 .Case("mips2", "mips2")
5162 .Case("mips3", "mips3")
5163 .Case("mips4", "mips4")
5164 .Case("mips5", "mips5")
5165 .Case("mips32", "mips32")
5166 .Case("mips32r2", "mips32r2")
5167 .Case("mips32r3", "mips32r3")
5168 .Case("mips32r5", "mips32r5")
5169 .Case("mips32r6", "mips32r6")
5170 .Case("mips64", "mips64")
5171 .Case("mips64r2", "mips64r2")
5172 .Case("mips64r3", "mips64r3")
5173 .Case("mips64r5", "mips64r5")
5174 .Case("mips64r6", "mips64r6")
5175 .Case("cnmips", "cnmips")
5176 .Case("r4000", "mips3") // This is an implementation of Mips3.
5179 if (ArchFeatureName.empty())
5180 return reportParseError("unsupported architecture");
5182 selectArch(ArchFeatureName);
5183 getTargetStreamer().emitDirectiveSetArch(Arch);
5187 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
5188 MCAsmParser &Parser = getParser();
5190 if (getLexer().isNot(AsmToken::EndOfStatement))
5191 return reportParseError("unexpected token, expected end of statement");
5195 llvm_unreachable("Unimplemented feature");
5196 case Mips::FeatureDSP:
5197 setFeatureBits(Mips::FeatureDSP, "dsp");
5198 getTargetStreamer().emitDirectiveSetDsp();
5200 case Mips::FeatureMicroMips:
5201 getTargetStreamer().emitDirectiveSetMicroMips();
5203 case Mips::FeatureMips1:
5204 selectArch("mips1");
5205 getTargetStreamer().emitDirectiveSetMips1();
5207 case Mips::FeatureMips2:
5208 selectArch("mips2");
5209 getTargetStreamer().emitDirectiveSetMips2();
5211 case Mips::FeatureMips3:
5212 selectArch("mips3");
5213 getTargetStreamer().emitDirectiveSetMips3();
5215 case Mips::FeatureMips4:
5216 selectArch("mips4");
5217 getTargetStreamer().emitDirectiveSetMips4();
5219 case Mips::FeatureMips5:
5220 selectArch("mips5");
5221 getTargetStreamer().emitDirectiveSetMips5();
5223 case Mips::FeatureMips32:
5224 selectArch("mips32");
5225 getTargetStreamer().emitDirectiveSetMips32();
5227 case Mips::FeatureMips32r2:
5228 selectArch("mips32r2");
5229 getTargetStreamer().emitDirectiveSetMips32R2();
5231 case Mips::FeatureMips32r3:
5232 selectArch("mips32r3");
5233 getTargetStreamer().emitDirectiveSetMips32R3();
5235 case Mips::FeatureMips32r5:
5236 selectArch("mips32r5");
5237 getTargetStreamer().emitDirectiveSetMips32R5();
5239 case Mips::FeatureMips32r6:
5240 selectArch("mips32r6");
5241 getTargetStreamer().emitDirectiveSetMips32R6();
5243 case Mips::FeatureMips64:
5244 selectArch("mips64");
5245 getTargetStreamer().emitDirectiveSetMips64();
5247 case Mips::FeatureMips64r2:
5248 selectArch("mips64r2");
5249 getTargetStreamer().emitDirectiveSetMips64R2();
5251 case Mips::FeatureMips64r3:
5252 selectArch("mips64r3");
5253 getTargetStreamer().emitDirectiveSetMips64R3();
5255 case Mips::FeatureMips64r5:
5256 selectArch("mips64r5");
5257 getTargetStreamer().emitDirectiveSetMips64R5();
5259 case Mips::FeatureMips64r6:
5260 selectArch("mips64r6");
5261 getTargetStreamer().emitDirectiveSetMips64R6();
5267 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
5268 MCAsmParser &Parser = getParser();
5269 if (getLexer().isNot(AsmToken::Comma)) {
5270 SMLoc Loc = getLexer().getLoc();
5271 Parser.eatToEndOfStatement();
5272 return Error(Loc, ErrorStr);
5275 Parser.Lex(); // Eat the comma.
5279 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
5280 // In this class, it is only used for .cprestore.
5281 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
5282 // MipsTargetELFStreamer and MipsAsmParser.
5283 bool MipsAsmParser::isPicAndNotNxxAbi() {
5284 return inPicMode() && !(isABI_N32() || isABI_N64());
5287 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
5288 if (AssemblerOptions.back()->isReorder())
5289 Warning(Loc, ".cpload should be inside a noreorder section");
5291 if (inMips16Mode()) {
5292 reportParseError(".cpload is not supported in Mips16 mode");
5296 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
5297 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
5298 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5299 reportParseError("expected register containing function address");
5303 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
5304 if (!RegOpnd.isGPRAsmReg()) {
5305 reportParseError(RegOpnd.getStartLoc(), "invalid register");
5309 // If this is not the end of the statement, report an error.
5310 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5311 reportParseError("unexpected token, expected end of statement");
5315 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5319 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5320 MCAsmParser &Parser = getParser();
5322 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5323 // is used in non-PIC mode.
5325 if (inMips16Mode()) {
5326 reportParseError(".cprestore is not supported in Mips16 mode");
5330 // Get the stack offset value.
5331 const MCExpr *StackOffset;
5332 int64_t StackOffsetVal;
5333 if (Parser.parseExpression(StackOffset)) {
5334 reportParseError("expected stack offset value");
5338 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5339 reportParseError("stack offset is not an absolute expression");
5343 if (StackOffsetVal < 0) {
5344 Warning(Loc, ".cprestore with negative stack offset has no effect");
5345 IsCpRestoreSet = false;
5347 IsCpRestoreSet = true;
5348 CpRestoreOffset = StackOffsetVal;
5351 // If this is not the end of the statement, report an error.
5352 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5353 reportParseError("unexpected token, expected end of statement");
5357 // Store the $gp on the stack.
5358 SmallVector<MCInst, 3> StoreInsts;
5359 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5362 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
5363 Parser.Lex(); // Consume the EndOfStatement.
5367 bool MipsAsmParser::parseDirectiveCPSetup() {
5368 MCAsmParser &Parser = getParser();
5371 bool SaveIsReg = true;
5373 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5374 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5375 if (ResTy == MatchOperand_NoMatch) {
5376 reportParseError("expected register containing function address");
5377 Parser.eatToEndOfStatement();
5381 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5382 if (!FuncRegOpnd.isGPRAsmReg()) {
5383 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5384 Parser.eatToEndOfStatement();
5388 FuncReg = FuncRegOpnd.getGPR32Reg();
5391 if (!eatComma("unexpected token, expected comma"))
5394 ResTy = parseAnyRegister(TmpReg);
5395 if (ResTy == MatchOperand_NoMatch) {
5396 const MCExpr *OffsetExpr;
5398 SMLoc ExprLoc = getLexer().getLoc();
5400 if (Parser.parseExpression(OffsetExpr) ||
5401 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5402 reportParseError(ExprLoc, "expected save register or stack offset");
5403 Parser.eatToEndOfStatement();
5410 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5411 if (!SaveOpnd.isGPRAsmReg()) {
5412 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5413 Parser.eatToEndOfStatement();
5416 Save = SaveOpnd.getGPR32Reg();
5419 if (!eatComma("unexpected token, expected comma"))
5423 if (Parser.parseExpression(Expr)) {
5424 reportParseError("expected expression");
5428 if (Expr->getKind() != MCExpr::SymbolRef) {
5429 reportParseError("expected symbol");
5432 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5434 CpSaveLocation = Save;
5435 CpSaveLocationIsRegister = SaveIsReg;
5437 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5442 bool MipsAsmParser::parseDirectiveCPReturn() {
5443 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5444 CpSaveLocationIsRegister);
5448 bool MipsAsmParser::parseDirectiveNaN() {
5449 MCAsmParser &Parser = getParser();
5450 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5451 const AsmToken &Tok = Parser.getTok();
5453 if (Tok.getString() == "2008") {
5455 getTargetStreamer().emitDirectiveNaN2008();
5457 } else if (Tok.getString() == "legacy") {
5459 getTargetStreamer().emitDirectiveNaNLegacy();
5463 // If we don't recognize the option passed to the .nan
5464 // directive (e.g. no option or unknown option), emit an error.
5465 reportParseError("invalid option in .nan directive");
5469 bool MipsAsmParser::parseDirectiveSet() {
5470 MCAsmParser &Parser = getParser();
5471 // Get the next token.
5472 const AsmToken &Tok = Parser.getTok();
5474 if (Tok.getString() == "noat") {
5475 return parseSetNoAtDirective();
5476 } else if (Tok.getString() == "at") {
5477 return parseSetAtDirective();
5478 } else if (Tok.getString() == "arch") {
5479 return parseSetArchDirective();
5480 } else if (Tok.getString() == "fp") {
5481 return parseSetFpDirective();
5482 } else if (Tok.getString() == "oddspreg") {
5483 return parseSetOddSPRegDirective();
5484 } else if (Tok.getString() == "nooddspreg") {
5485 return parseSetNoOddSPRegDirective();
5486 } else if (Tok.getString() == "pop") {
5487 return parseSetPopDirective();
5488 } else if (Tok.getString() == "push") {
5489 return parseSetPushDirective();
5490 } else if (Tok.getString() == "reorder") {
5491 return parseSetReorderDirective();
5492 } else if (Tok.getString() == "noreorder") {
5493 return parseSetNoReorderDirective();
5494 } else if (Tok.getString() == "macro") {
5495 return parseSetMacroDirective();
5496 } else if (Tok.getString() == "nomacro") {
5497 return parseSetNoMacroDirective();
5498 } else if (Tok.getString() == "mips16") {
5499 return parseSetMips16Directive();
5500 } else if (Tok.getString() == "nomips16") {
5501 return parseSetNoMips16Directive();
5502 } else if (Tok.getString() == "nomicromips") {
5503 getTargetStreamer().emitDirectiveSetNoMicroMips();
5504 Parser.eatToEndOfStatement();
5506 } else if (Tok.getString() == "micromips") {
5507 return parseSetFeature(Mips::FeatureMicroMips);
5508 } else if (Tok.getString() == "mips0") {
5509 return parseSetMips0Directive();
5510 } else if (Tok.getString() == "mips1") {
5511 return parseSetFeature(Mips::FeatureMips1);
5512 } else if (Tok.getString() == "mips2") {
5513 return parseSetFeature(Mips::FeatureMips2);
5514 } else if (Tok.getString() == "mips3") {
5515 return parseSetFeature(Mips::FeatureMips3);
5516 } else if (Tok.getString() == "mips4") {
5517 return parseSetFeature(Mips::FeatureMips4);
5518 } else if (Tok.getString() == "mips5") {
5519 return parseSetFeature(Mips::FeatureMips5);
5520 } else if (Tok.getString() == "mips32") {
5521 return parseSetFeature(Mips::FeatureMips32);
5522 } else if (Tok.getString() == "mips32r2") {
5523 return parseSetFeature(Mips::FeatureMips32r2);
5524 } else if (Tok.getString() == "mips32r3") {
5525 return parseSetFeature(Mips::FeatureMips32r3);
5526 } else if (Tok.getString() == "mips32r5") {
5527 return parseSetFeature(Mips::FeatureMips32r5);
5528 } else if (Tok.getString() == "mips32r6") {
5529 return parseSetFeature(Mips::FeatureMips32r6);
5530 } else if (Tok.getString() == "mips64") {
5531 return parseSetFeature(Mips::FeatureMips64);
5532 } else if (Tok.getString() == "mips64r2") {
5533 return parseSetFeature(Mips::FeatureMips64r2);
5534 } else if (Tok.getString() == "mips64r3") {
5535 return parseSetFeature(Mips::FeatureMips64r3);
5536 } else if (Tok.getString() == "mips64r5") {
5537 return parseSetFeature(Mips::FeatureMips64r5);
5538 } else if (Tok.getString() == "mips64r6") {
5539 return parseSetFeature(Mips::FeatureMips64r6);
5540 } else if (Tok.getString() == "dsp") {
5541 return parseSetFeature(Mips::FeatureDSP);
5542 } else if (Tok.getString() == "nodsp") {
5543 return parseSetNoDspDirective();
5544 } else if (Tok.getString() == "msa") {
5545 return parseSetMsaDirective();
5546 } else if (Tok.getString() == "nomsa") {
5547 return parseSetNoMsaDirective();
5548 } else if (Tok.getString() == "softfloat") {
5549 return parseSetSoftFloatDirective();
5550 } else if (Tok.getString() == "hardfloat") {
5551 return parseSetHardFloatDirective();
5553 // It is just an identifier, look for an assignment.
5554 parseSetAssignment();
5561 /// parseDataDirective
5562 /// ::= .word [ expression (, expression)* ]
5563 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5564 MCAsmParser &Parser = getParser();
5565 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5567 const MCExpr *Value;
5568 if (getParser().parseExpression(Value))
5571 getParser().getStreamer().EmitValue(Value, Size);
5573 if (getLexer().is(AsmToken::EndOfStatement))
5576 if (getLexer().isNot(AsmToken::Comma))
5577 return Error(L, "unexpected token, expected comma");
5586 /// parseDirectiveGpWord
5587 /// ::= .gpword local_sym
5588 bool MipsAsmParser::parseDirectiveGpWord() {
5589 MCAsmParser &Parser = getParser();
5590 const MCExpr *Value;
5591 // EmitGPRel32Value requires an expression, so we are using base class
5592 // method to evaluate the expression.
5593 if (getParser().parseExpression(Value))
5595 getParser().getStreamer().EmitGPRel32Value(Value);
5597 if (getLexer().isNot(AsmToken::EndOfStatement))
5598 return Error(getLexer().getLoc(),
5599 "unexpected token, expected end of statement");
5600 Parser.Lex(); // Eat EndOfStatement token.
5604 /// parseDirectiveGpDWord
5605 /// ::= .gpdword local_sym
5606 bool MipsAsmParser::parseDirectiveGpDWord() {
5607 MCAsmParser &Parser = getParser();
5608 const MCExpr *Value;
5609 // EmitGPRel64Value requires an expression, so we are using base class
5610 // method to evaluate the expression.
5611 if (getParser().parseExpression(Value))
5613 getParser().getStreamer().EmitGPRel64Value(Value);
5615 if (getLexer().isNot(AsmToken::EndOfStatement))
5616 return Error(getLexer().getLoc(),
5617 "unexpected token, expected end of statement");
5618 Parser.Lex(); // Eat EndOfStatement token.
5622 bool MipsAsmParser::parseDirectiveOption() {
5623 MCAsmParser &Parser = getParser();
5624 // Get the option token.
5625 AsmToken Tok = Parser.getTok();
5626 // At the moment only identifiers are supported.
5627 if (Tok.isNot(AsmToken::Identifier)) {
5628 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5629 Parser.eatToEndOfStatement();
5633 StringRef Option = Tok.getIdentifier();
5635 if (Option == "pic0") {
5636 // MipsAsmParser needs to know if the current PIC mode changes.
5637 IsPicEnabled = false;
5639 getTargetStreamer().emitDirectiveOptionPic0();
5641 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5642 Error(Parser.getTok().getLoc(),
5643 "unexpected token, expected end of statement");
5644 Parser.eatToEndOfStatement();
5649 if (Option == "pic2") {
5650 // MipsAsmParser needs to know if the current PIC mode changes.
5651 IsPicEnabled = true;
5653 getTargetStreamer().emitDirectiveOptionPic2();
5655 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5656 Error(Parser.getTok().getLoc(),
5657 "unexpected token, expected end of statement");
5658 Parser.eatToEndOfStatement();
5664 Warning(Parser.getTok().getLoc(),
5665 "unknown option, expected 'pic0' or 'pic2'");
5666 Parser.eatToEndOfStatement();
5670 /// parseInsnDirective
5672 bool MipsAsmParser::parseInsnDirective() {
5673 // If this is not the end of the statement, report an error.
5674 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5675 reportParseError("unexpected token, expected end of statement");
5679 // The actual label marking happens in
5680 // MipsELFStreamer::createPendingLabelRelocs().
5681 getTargetStreamer().emitDirectiveInsn();
5683 getParser().Lex(); // Eat EndOfStatement token.
5687 /// parseDirectiveModule
5688 /// ::= .module oddspreg
5689 /// ::= .module nooddspreg
5690 /// ::= .module fp=value
5691 /// ::= .module softfloat
5692 /// ::= .module hardfloat
5693 bool MipsAsmParser::parseDirectiveModule() {
5694 MCAsmParser &Parser = getParser();
5695 MCAsmLexer &Lexer = getLexer();
5696 SMLoc L = Lexer.getLoc();
5698 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5699 // TODO : get a better message.
5700 reportParseError(".module directive must appear before any code");
5705 if (Parser.parseIdentifier(Option)) {
5706 reportParseError("expected .module option identifier");
5710 if (Option == "oddspreg") {
5711 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5713 // Synchronize the abiflags information with the FeatureBits information we
5715 getTargetStreamer().updateABIInfo(*this);
5717 // If printing assembly, use the recently updated abiflags information.
5718 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5719 // emitted at the end).
5720 getTargetStreamer().emitDirectiveModuleOddSPReg();
5722 // If this is not the end of the statement, report an error.
5723 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5724 reportParseError("unexpected token, expected end of statement");
5728 return false; // parseDirectiveModule has finished successfully.
5729 } else if (Option == "nooddspreg") {
5731 Error(L, "'.module nooddspreg' requires the O32 ABI");
5735 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5737 // Synchronize the abiflags information with the FeatureBits information we
5739 getTargetStreamer().updateABIInfo(*this);
5741 // If printing assembly, use the recently updated abiflags information.
5742 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5743 // emitted at the end).
5744 getTargetStreamer().emitDirectiveModuleOddSPReg();
5746 // If this is not the end of the statement, report an error.
5747 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5748 reportParseError("unexpected token, expected end of statement");
5752 return false; // parseDirectiveModule has finished successfully.
5753 } else if (Option == "fp") {
5754 return parseDirectiveModuleFP();
5755 } else if (Option == "softfloat") {
5756 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5758 // Synchronize the ABI Flags information with the FeatureBits information we
5760 getTargetStreamer().updateABIInfo(*this);
5762 // If printing assembly, use the recently updated ABI Flags information.
5763 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5765 getTargetStreamer().emitDirectiveModuleSoftFloat();
5767 // If this is not the end of the statement, report an error.
5768 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5769 reportParseError("unexpected token, expected end of statement");
5773 return false; // parseDirectiveModule has finished successfully.
5774 } else if (Option == "hardfloat") {
5775 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5777 // Synchronize the ABI Flags information with the FeatureBits information we
5779 getTargetStreamer().updateABIInfo(*this);
5781 // If printing assembly, use the recently updated ABI Flags information.
5782 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5784 getTargetStreamer().emitDirectiveModuleHardFloat();
5786 // If this is not the end of the statement, report an error.
5787 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5788 reportParseError("unexpected token, expected end of statement");
5792 return false; // parseDirectiveModule has finished successfully.
5794 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5798 /// parseDirectiveModuleFP
5802 bool MipsAsmParser::parseDirectiveModuleFP() {
5803 MCAsmParser &Parser = getParser();
5804 MCAsmLexer &Lexer = getLexer();
5806 if (Lexer.isNot(AsmToken::Equal)) {
5807 reportParseError("unexpected token, expected equals sign '='");
5810 Parser.Lex(); // Eat '=' token.
5812 MipsABIFlagsSection::FpABIKind FpABI;
5813 if (!parseFpABIValue(FpABI, ".module"))
5816 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5817 reportParseError("unexpected token, expected end of statement");
5821 // Synchronize the abiflags information with the FeatureBits information we
5823 getTargetStreamer().updateABIInfo(*this);
5825 // If printing assembly, use the recently updated abiflags information.
5826 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5827 // emitted at the end).
5828 getTargetStreamer().emitDirectiveModuleFP();
5830 Parser.Lex(); // Consume the EndOfStatement.
5834 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5835 StringRef Directive) {
5836 MCAsmParser &Parser = getParser();
5837 MCAsmLexer &Lexer = getLexer();
5838 bool ModuleLevelOptions = Directive == ".module";
5840 if (Lexer.is(AsmToken::Identifier)) {
5841 StringRef Value = Parser.getTok().getString();
5844 if (Value != "xx") {
5845 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5850 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5854 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5855 if (ModuleLevelOptions) {
5856 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5857 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5859 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5860 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5865 if (Lexer.is(AsmToken::Integer)) {
5866 unsigned Value = Parser.getTok().getIntVal();
5869 if (Value != 32 && Value != 64) {
5870 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5876 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5880 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5881 if (ModuleLevelOptions) {
5882 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5883 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5885 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5886 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5889 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5890 if (ModuleLevelOptions) {
5891 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5892 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5894 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5895 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5905 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5906 MCAsmParser &Parser = getParser();
5907 StringRef IDVal = DirectiveID.getString();
5909 if (IDVal == ".cpload")
5910 return parseDirectiveCpLoad(DirectiveID.getLoc());
5911 if (IDVal == ".cprestore")
5912 return parseDirectiveCpRestore(DirectiveID.getLoc());
5913 if (IDVal == ".dword") {
5914 parseDataDirective(8, DirectiveID.getLoc());
5917 if (IDVal == ".ent") {
5918 StringRef SymbolName;
5920 if (Parser.parseIdentifier(SymbolName)) {
5921 reportParseError("expected identifier after .ent");
5925 // There's an undocumented extension that allows an integer to
5926 // follow the name of the procedure which AFAICS is ignored by GAS.
5927 // Example: .ent foo,2
5928 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5929 if (getLexer().isNot(AsmToken::Comma)) {
5930 // Even though we accept this undocumented extension for compatibility
5931 // reasons, the additional integer argument does not actually change
5932 // the behaviour of the '.ent' directive, so we would like to discourage
5933 // its use. We do this by not referring to the extended version in
5934 // error messages which are not directly related to its use.
5935 reportParseError("unexpected token, expected end of statement");
5938 Parser.Lex(); // Eat the comma.
5939 const MCExpr *DummyNumber;
5940 int64_t DummyNumberVal;
5941 // If the user was explicitly trying to use the extended version,
5942 // we still give helpful extension-related error messages.
5943 if (Parser.parseExpression(DummyNumber)) {
5944 reportParseError("expected number after comma");
5947 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5948 reportParseError("expected an absolute expression after comma");
5953 // If this is not the end of the statement, report an error.
5954 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5955 reportParseError("unexpected token, expected end of statement");
5959 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5961 getTargetStreamer().emitDirectiveEnt(*Sym);
5963 IsCpRestoreSet = false;
5967 if (IDVal == ".end") {
5968 StringRef SymbolName;
5970 if (Parser.parseIdentifier(SymbolName)) {
5971 reportParseError("expected identifier after .end");
5975 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5976 reportParseError("unexpected token, expected end of statement");
5980 if (CurrentFn == nullptr) {
5981 reportParseError(".end used without .ent");
5985 if ((SymbolName != CurrentFn->getName())) {
5986 reportParseError(".end symbol does not match .ent symbol");
5990 getTargetStreamer().emitDirectiveEnd(SymbolName);
5991 CurrentFn = nullptr;
5992 IsCpRestoreSet = false;
5996 if (IDVal == ".frame") {
5997 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5998 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5999 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6000 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6001 reportParseError("expected stack register");
6005 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6006 if (!StackRegOpnd.isGPRAsmReg()) {
6007 reportParseError(StackRegOpnd.getStartLoc(),
6008 "expected general purpose register");
6011 unsigned StackReg = StackRegOpnd.getGPR32Reg();
6013 if (Parser.getTok().is(AsmToken::Comma))
6016 reportParseError("unexpected token, expected comma");
6020 // Parse the frame size.
6021 const MCExpr *FrameSize;
6022 int64_t FrameSizeVal;
6024 if (Parser.parseExpression(FrameSize)) {
6025 reportParseError("expected frame size value");
6029 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
6030 reportParseError("frame size not an absolute expression");
6034 if (Parser.getTok().is(AsmToken::Comma))
6037 reportParseError("unexpected token, expected comma");
6041 // Parse the return register.
6043 ResTy = parseAnyRegister(TmpReg);
6044 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6045 reportParseError("expected return register");
6049 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6050 if (!ReturnRegOpnd.isGPRAsmReg()) {
6051 reportParseError(ReturnRegOpnd.getStartLoc(),
6052 "expected general purpose register");
6056 // If this is not the end of the statement, report an error.
6057 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6058 reportParseError("unexpected token, expected end of statement");
6062 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
6063 ReturnRegOpnd.getGPR32Reg());
6064 IsCpRestoreSet = false;
6068 if (IDVal == ".set") {
6069 return parseDirectiveSet();
6072 if (IDVal == ".mask" || IDVal == ".fmask") {
6073 // .mask bitmask, frame_offset
6074 // bitmask: One bit for each register used.
6075 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
6076 // first register is expected to be saved.
6078 // .mask 0x80000000, -4
6079 // .fmask 0x80000000, -4
6082 // Parse the bitmask
6083 const MCExpr *BitMask;
6086 if (Parser.parseExpression(BitMask)) {
6087 reportParseError("expected bitmask value");
6091 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
6092 reportParseError("bitmask not an absolute expression");
6096 if (Parser.getTok().is(AsmToken::Comma))
6099 reportParseError("unexpected token, expected comma");
6103 // Parse the frame_offset
6104 const MCExpr *FrameOffset;
6105 int64_t FrameOffsetVal;
6107 if (Parser.parseExpression(FrameOffset)) {
6108 reportParseError("expected frame offset value");
6112 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
6113 reportParseError("frame offset not an absolute expression");
6117 // If this is not the end of the statement, report an error.
6118 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6119 reportParseError("unexpected token, expected end of statement");
6123 if (IDVal == ".mask")
6124 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
6126 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6130 if (IDVal == ".nan")
6131 return parseDirectiveNaN();
6133 if (IDVal == ".gpword") {
6134 parseDirectiveGpWord();
6138 if (IDVal == ".gpdword") {
6139 parseDirectiveGpDWord();
6143 if (IDVal == ".word") {
6144 parseDataDirective(4, DirectiveID.getLoc());
6148 if (IDVal == ".option")
6149 return parseDirectiveOption();
6151 if (IDVal == ".abicalls") {
6152 getTargetStreamer().emitDirectiveAbiCalls();
6153 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6154 Error(Parser.getTok().getLoc(),
6155 "unexpected token, expected end of statement");
6157 Parser.eatToEndOfStatement();
6162 if (IDVal == ".cpsetup")
6163 return parseDirectiveCPSetup();
6165 if (IDVal == ".cpreturn")
6166 return parseDirectiveCPReturn();
6168 if (IDVal == ".module")
6169 return parseDirectiveModule();
6171 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
6172 return parseInternalDirectiveReallowModule();
6174 if (IDVal == ".insn")
6175 return parseInsnDirective();
6180 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
6181 // If this is not the end of the statement, report an error.
6182 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6183 reportParseError("unexpected token, expected end of statement");
6187 getTargetStreamer().reallowModuleDirective();
6189 getParser().Lex(); // Eat EndOfStatement token.
6193 extern "C" void LLVMInitializeMipsAsmParser() {
6194 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
6195 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
6196 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
6197 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
6200 #define GET_REGISTER_MATCHER
6201 #define GET_MATCHER_IMPLEMENTATION
6202 #include "MipsGenAsmMatcher.inc"