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);
1712 // If it's an external/weak symbol, we expand to:
1713 // lw/ld $25, 0($gp)
1714 // R_(MICRO)MIPS_CALL16 label
1716 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1718 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1719 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1720 } else if (isABI_N32() || isABI_N64()) {
1721 // If it's an external/weak symbol, we expand to:
1722 // lw/ld $25, 0($gp)
1723 // R_(MICRO)MIPS_GOT_DISP label
1725 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1727 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1728 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1733 if (IsCpRestoreSet && inMicroMipsMode())
1734 JalrInst.setOpcode(Mips::JALRS_MM);
1736 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1737 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1738 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1740 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1741 // This relocation is supposed to be an optimization hint for the linker
1742 // and is not necessary for correctness.
1745 ExpandedJalSym = true;
1748 if (MCID.mayLoad() || MCID.mayStore()) {
1749 // Check the offset of memory operand, if it is a symbol
1750 // reference or immediate we may have to expand instructions.
1751 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1752 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1753 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1754 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1755 MCOperand &Op = Inst.getOperand(i);
1757 int MemOffset = Op.getImm();
1758 if (MemOffset < -32768 || MemOffset > 32767) {
1759 // Offset can't exceed 16bit value.
1760 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1763 } else if (Op.isExpr()) {
1764 const MCExpr *Expr = Op.getExpr();
1765 if (Expr->getKind() == MCExpr::SymbolRef) {
1766 const MCSymbolRefExpr *SR =
1767 static_cast<const MCSymbolRefExpr *>(Expr);
1768 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1770 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1773 } else if (!isEvaluated(Expr)) {
1774 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1782 if (inMicroMipsMode()) {
1783 if (MCID.mayLoad()) {
1784 // Try to create 16-bit GP relative load instruction.
1785 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1786 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1787 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1788 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1789 MCOperand &Op = Inst.getOperand(i);
1791 int MemOffset = Op.getImm();
1792 MCOperand &DstReg = Inst.getOperand(0);
1793 MCOperand &BaseReg = Inst.getOperand(1);
1794 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1795 getContext().getRegisterInfo()->getRegClass(
1796 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1797 (BaseReg.getReg() == Mips::GP ||
1798 BaseReg.getReg() == Mips::GP_64)) {
1800 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1801 IDLoc, Instructions);
1809 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1814 switch (Inst.getOpcode()) {
1817 case Mips::ADDIUS5_MM:
1818 Opnd = Inst.getOperand(2);
1820 return Error(IDLoc, "expected immediate operand kind");
1821 Imm = Opnd.getImm();
1822 if (Imm < -8 || Imm > 7)
1823 return Error(IDLoc, "immediate operand value out of range");
1825 case Mips::ADDIUSP_MM:
1826 Opnd = Inst.getOperand(0);
1828 return Error(IDLoc, "expected immediate operand kind");
1829 Imm = Opnd.getImm();
1830 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1832 return Error(IDLoc, "immediate operand value out of range");
1834 case Mips::SLL16_MM:
1835 case Mips::SRL16_MM:
1836 Opnd = Inst.getOperand(2);
1838 return Error(IDLoc, "expected immediate operand kind");
1839 Imm = Opnd.getImm();
1840 if (Imm < 1 || Imm > 8)
1841 return Error(IDLoc, "immediate operand value out of range");
1844 Opnd = Inst.getOperand(1);
1846 return Error(IDLoc, "expected immediate operand kind");
1847 Imm = Opnd.getImm();
1848 if (Imm < -1 || Imm > 126)
1849 return Error(IDLoc, "immediate operand value out of range");
1851 case Mips::ADDIUR2_MM:
1852 Opnd = Inst.getOperand(2);
1854 return Error(IDLoc, "expected immediate operand kind");
1855 Imm = Opnd.getImm();
1856 if (!(Imm == 1 || Imm == -1 ||
1857 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1858 return Error(IDLoc, "immediate operand value out of range");
1860 case Mips::ADDIUR1SP_MM:
1861 Opnd = Inst.getOperand(1);
1863 return Error(IDLoc, "expected immediate operand kind");
1864 Imm = Opnd.getImm();
1865 if (OffsetToAlignment(Imm, 4LL))
1866 return Error(IDLoc, "misaligned immediate operand value");
1867 if (Imm < 0 || Imm > 255)
1868 return Error(IDLoc, "immediate operand value out of range");
1870 case Mips::ANDI16_MM:
1871 Opnd = Inst.getOperand(2);
1873 return Error(IDLoc, "expected immediate operand kind");
1874 Imm = Opnd.getImm();
1875 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1876 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1877 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1878 return Error(IDLoc, "immediate operand value out of range");
1880 case Mips::LBU16_MM:
1881 Opnd = Inst.getOperand(2);
1883 return Error(IDLoc, "expected immediate operand kind");
1884 Imm = Opnd.getImm();
1885 if (Imm < -1 || Imm > 14)
1886 return Error(IDLoc, "immediate operand value out of range");
1895 case Mips::SB16_MMR6:
1896 Opnd = Inst.getOperand(2);
1898 return Error(IDLoc, "expected immediate operand kind");
1899 Imm = Opnd.getImm();
1900 if (Imm < 0 || Imm > 15)
1901 return Error(IDLoc, "immediate operand value out of range");
1903 case Mips::LHU16_MM:
1905 case Mips::SH16_MMR6:
1906 Opnd = Inst.getOperand(2);
1908 return Error(IDLoc, "expected immediate operand kind");
1909 Imm = Opnd.getImm();
1910 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1911 return Error(IDLoc, "immediate operand value out of range");
1915 case Mips::SW16_MMR6:
1916 Opnd = Inst.getOperand(2);
1918 return Error(IDLoc, "expected immediate operand kind");
1919 Imm = Opnd.getImm();
1920 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1921 return Error(IDLoc, "immediate operand value out of range");
1923 case Mips::PREFX_MM:
1926 Opnd = Inst.getOperand(2);
1928 return Error(IDLoc, "expected immediate operand kind");
1929 Imm = Opnd.getImm();
1930 if (!isUInt<5>(Imm))
1931 return Error(IDLoc, "immediate operand value out of range");
1933 case Mips::ADDIUPC_MM:
1934 MCOperand Opnd = Inst.getOperand(1);
1936 return Error(IDLoc, "expected immediate operand kind");
1937 int Imm = Opnd.getImm();
1938 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1939 return Error(IDLoc, "immediate operand value out of range");
1944 MacroExpanderResultTy ExpandResult =
1945 tryExpandInstruction(Inst, IDLoc, Instructions);
1946 switch (ExpandResult) {
1948 Instructions.push_back(Inst);
1956 // If this instruction has a delay slot and .set reorder is active,
1957 // emit a NOP after it.
1958 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1959 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1961 if ((Inst.getOpcode() == Mips::JalOneReg ||
1962 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1963 isPicAndNotNxxAbi()) {
1964 if (IsCpRestoreSet) {
1965 // We need a NOP between the JALR and the LW:
1966 // If .set reorder has been used, we've already emitted a NOP.
1967 // If .set noreorder has been used, we need to emit a NOP at this point.
1968 if (!AssemblerOptions.back()->isReorder())
1969 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1971 // Load the $gp from the stack.
1972 SmallVector<MCInst, 3> LoadInsts;
1973 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1976 for (const MCInst &Inst : LoadInsts)
1977 Instructions.push_back(Inst);
1980 Warning(IDLoc, "no .cprestore used in PIC mode");
1986 MipsAsmParser::MacroExpanderResultTy
1987 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
1988 SmallVectorImpl<MCInst> &Instructions) {
1989 switch (Inst.getOpcode()) {
1991 return MER_NotAMacro;
1992 case Mips::LoadImm32:
1993 return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
1995 case Mips::LoadImm64:
1996 return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
1998 case Mips::LoadAddrImm32:
1999 case Mips::LoadAddrImm64:
2000 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2001 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2002 "expected immediate operand kind");
2004 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2006 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2010 case Mips::LoadAddrReg32:
2011 case Mips::LoadAddrReg64:
2012 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2013 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2014 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2015 "expected immediate operand kind");
2017 return expandLoadAddress(Inst.getOperand(0).getReg(),
2018 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2019 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2023 case Mips::B_MM_Pseudo:
2024 case Mips::B_MMR6_Pseudo:
2025 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
2029 return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
2031 case Mips::JalOneReg:
2032 case Mips::JalTwoReg:
2033 return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
2037 return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2054 case Mips::BLTImmMacro:
2055 case Mips::BLEImmMacro:
2056 case Mips::BGEImmMacro:
2057 case Mips::BGTImmMacro:
2058 case Mips::BLTUImmMacro:
2059 case Mips::BLEUImmMacro:
2060 case Mips::BGEUImmMacro:
2061 case Mips::BGTUImmMacro:
2062 case Mips::BLTLImmMacro:
2063 case Mips::BLELImmMacro:
2064 case Mips::BGELImmMacro:
2065 case Mips::BGTLImmMacro:
2066 case Mips::BLTULImmMacro:
2067 case Mips::BLEULImmMacro:
2068 case Mips::BGEULImmMacro:
2069 case Mips::BGTULImmMacro:
2070 return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2072 case Mips::SDivMacro:
2073 return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2075 case Mips::DSDivMacro:
2076 return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2078 case Mips::UDivMacro:
2079 return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2081 case Mips::DUDivMacro:
2082 return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2085 return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2087 return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2089 return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2091 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2097 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2098 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2099 int64_t ImmValue = Inst.getOperand(2).getImm();
2100 if (isInt<16>(ImmValue))
2101 return MER_NotAMacro;
2102 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2105 return MER_NotAMacro;
2109 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2110 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2111 int64_t ImmValue = Inst.getOperand(2).getImm();
2112 if (isUInt<16>(ImmValue))
2113 return MER_NotAMacro;
2114 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2117 return MER_NotAMacro;
2120 return expandRotation(Inst, IDLoc, Instructions) ? MER_Fail
2124 return expandRotationImm(Inst, IDLoc, Instructions) ? MER_Fail
2128 return expandDRotation(Inst, IDLoc, Instructions) ? MER_Fail
2132 return expandDRotationImm(Inst, IDLoc, Instructions) ? MER_Fail
2137 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2138 SmallVectorImpl<MCInst> &Instructions) {
2139 // Create a JALR instruction which is going to replace the pseudo-JAL.
2141 JalrInst.setLoc(IDLoc);
2142 const MCOperand FirstRegOp = Inst.getOperand(0);
2143 const unsigned Opcode = Inst.getOpcode();
2145 if (Opcode == Mips::JalOneReg) {
2146 // jal $rs => jalr $rs
2147 if (IsCpRestoreSet && inMicroMipsMode()) {
2148 JalrInst.setOpcode(Mips::JALRS16_MM);
2149 JalrInst.addOperand(FirstRegOp);
2150 } else if (inMicroMipsMode()) {
2151 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2152 JalrInst.addOperand(FirstRegOp);
2154 JalrInst.setOpcode(Mips::JALR);
2155 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2156 JalrInst.addOperand(FirstRegOp);
2158 } else if (Opcode == Mips::JalTwoReg) {
2159 // jal $rd, $rs => jalr $rd, $rs
2160 if (IsCpRestoreSet && inMicroMipsMode())
2161 JalrInst.setOpcode(Mips::JALRS_MM);
2163 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2164 JalrInst.addOperand(FirstRegOp);
2165 const MCOperand SecondRegOp = Inst.getOperand(1);
2166 JalrInst.addOperand(SecondRegOp);
2168 Instructions.push_back(JalrInst);
2170 // If .set reorder is active and branch instruction has a delay slot,
2171 // emit a NOP after it.
2172 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2173 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2174 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2180 /// Can the value be represented by a unsigned N-bit value and a shift left?
2181 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2182 unsigned BitNum = findFirstSet(x);
2184 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2187 /// Load (or add) an immediate into a register.
2189 /// @param ImmValue The immediate to load.
2190 /// @param DstReg The register that will hold the immediate.
2191 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2192 /// for a simple initialization.
2193 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2194 /// @param IsAddress True if the immediate represents an address. False if it
2196 /// @param IDLoc Location of the immediate in the source file.
2197 /// @param Instructions The instructions emitted by this expansion.
2198 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2199 unsigned SrcReg, bool Is32BitImm,
2200 bool IsAddress, SMLoc IDLoc,
2201 SmallVectorImpl<MCInst> &Instructions) {
2202 if (!Is32BitImm && !isGP64bit()) {
2203 Error(IDLoc, "instruction requires a 64-bit architecture");
2208 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2209 // Sign extend up to 64-bit so that the predicates match the hardware
2210 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2212 ImmValue = SignExtend64<32>(ImmValue);
2214 Error(IDLoc, "instruction requires a 32-bit immediate");
2219 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2220 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2222 bool UseSrcReg = false;
2223 if (SrcReg != Mips::NoRegister)
2226 unsigned TmpReg = DstReg;
2227 if (UseSrcReg && (DstReg == SrcReg)) {
2228 // At this point we need AT to perform the expansions and we exit if it is
2230 unsigned ATReg = getATReg(IDLoc);
2236 if (isInt<16>(ImmValue)) {
2240 // This doesn't quite follow the usual ABI expectations for N32 but matches
2241 // traditional assembler behaviour. N32 would normally use addiu for both
2242 // integers and addresses.
2243 if (IsAddress && !Is32BitImm) {
2244 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2248 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2252 if (isUInt<16>(ImmValue)) {
2253 unsigned TmpReg = DstReg;
2254 if (SrcReg == DstReg) {
2255 TmpReg = getATReg(IDLoc);
2260 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2262 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2266 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2267 warnIfNoMacro(IDLoc);
2269 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2270 uint16_t Bits15To0 = ImmValue & 0xffff;
2272 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2273 // Traditional behaviour seems to special case this particular value. It's
2274 // not clear why other masks are handled differently.
2275 if (ImmValue == 0xffffffff) {
2276 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2277 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2279 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2283 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2285 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2286 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2288 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2290 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2294 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2296 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2298 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2302 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2304 Error(IDLoc, "instruction requires a 32-bit immediate");
2308 // Traditionally, these immediates are shifted as little as possible and as
2309 // such we align the most significant bit to bit 15 of our temporary.
2310 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2311 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2312 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2313 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2314 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2315 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2318 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2323 warnIfNoMacro(IDLoc);
2325 // The remaining case is packed with a sequence of dsll and ori with zeros
2326 // being omitted and any neighbouring dsll's being coalesced.
2327 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2329 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2330 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2331 IDLoc, Instructions))
2334 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2335 // skip it and defer the shift to the next chunk.
2336 unsigned ShiftCarriedForwards = 16;
2337 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2338 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2340 if (ImmChunk != 0) {
2341 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2343 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2344 ShiftCarriedForwards = 0;
2347 ShiftCarriedForwards += 16;
2349 ShiftCarriedForwards -= 16;
2351 // Finish any remaining shifts left by trailing zeros.
2352 if (ShiftCarriedForwards)
2353 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2357 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2362 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2363 SmallVectorImpl<MCInst> &Instructions) {
2364 const MCOperand &ImmOp = Inst.getOperand(1);
2365 assert(ImmOp.isImm() && "expected immediate operand kind");
2366 const MCOperand &DstRegOp = Inst.getOperand(0);
2367 assert(DstRegOp.isReg() && "expected register operand kind");
2369 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2370 Is32BitImm, false, IDLoc, Instructions))
2376 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2377 const MCOperand &Offset,
2378 bool Is32BitAddress, SMLoc IDLoc,
2379 SmallVectorImpl<MCInst> &Instructions) {
2380 // la can't produce a usable address when addresses are 64-bit.
2381 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2382 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2383 // We currently can't do this because we depend on the equality
2384 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2385 Error(IDLoc, "la used to load 64-bit address");
2386 // Continue as if we had 'dla' instead.
2387 Is32BitAddress = false;
2390 // dla requires 64-bit addresses.
2391 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2392 Error(IDLoc, "instruction requires a 64-bit architecture");
2396 if (!Offset.isImm())
2397 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2398 Is32BitAddress, IDLoc, Instructions);
2400 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2401 IDLoc, Instructions);
2404 bool MipsAsmParser::loadAndAddSymbolAddress(
2405 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2406 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2407 warnIfNoMacro(IDLoc);
2409 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2410 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2411 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2412 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2413 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2415 bool UseSrcReg = SrcReg != Mips::NoRegister;
2417 // This is the 64-bit symbol address expansion.
2418 if (ABI.ArePtrs64bit() && isGP64bit()) {
2419 // We always need AT for the 64-bit expansion.
2420 // If it is not available we exit.
2421 unsigned ATReg = getATReg(IDLoc);
2425 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2426 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2427 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2428 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2430 if (UseSrcReg && (DstReg == SrcReg)) {
2431 // If $rs is the same as $rd:
2432 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2433 // daddiu $at, $at, %higher(sym)
2434 // dsll $at, $at, 16
2435 // daddiu $at, $at, %hi(sym)
2436 // dsll $at, $at, 16
2437 // daddiu $at, $at, %lo(sym)
2438 // daddu $rd, $at, $rd
2439 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2441 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2442 IDLoc, Instructions);
2443 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2444 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2446 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2447 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2449 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2454 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2455 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2456 // lui $at, %hi(sym)
2457 // daddiu $rd, $rd, %higher(sym)
2458 // daddiu $at, $at, %lo(sym)
2459 // dsll32 $rd, $rd, 0
2460 // daddu $rd, $rd, $at
2461 // (daddu $rd, $rd, $rs)
2462 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2464 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2466 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2467 IDLoc, Instructions);
2468 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2470 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2471 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2473 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2478 // And now, the 32-bit symbol address expansion:
2479 // If $rs is the same as $rd:
2480 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2481 // ori $at, $at, %lo(sym)
2482 // addu $rd, $at, $rd
2483 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2484 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2485 // ori $rd, $rd, %lo(sym)
2486 // (addu $rd, $rd, $rs)
2487 unsigned TmpReg = DstReg;
2488 if (UseSrcReg && (DstReg == SrcReg)) {
2489 // If $rs is the same as $rd, we need to use AT.
2490 // If it is not available we exit.
2491 unsigned ATReg = getATReg(IDLoc);
2497 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2498 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2502 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2504 assert(DstReg == TmpReg);
2509 bool MipsAsmParser::expandUncondBranchMMPseudo(
2510 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2511 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2512 "unexpected number of operands");
2514 MCOperand Offset = Inst.getOperand(0);
2515 if (Offset.isExpr()) {
2517 Inst.setOpcode(Mips::BEQ_MM);
2518 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2519 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2520 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2522 assert(Offset.isImm() && "expected immediate operand kind");
2523 if (isInt<11>(Offset.getImm())) {
2524 // If offset fits into 11 bits then this instruction becomes microMIPS
2525 // 16-bit unconditional branch instruction.
2526 if (inMicroMipsMode())
2527 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2529 if (!isInt<17>(Offset.getImm()))
2530 Error(IDLoc, "branch target out of range");
2531 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2532 Error(IDLoc, "branch to misaligned address");
2534 Inst.setOpcode(Mips::BEQ_MM);
2535 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2536 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2537 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2540 Instructions.push_back(Inst);
2542 // If .set reorder is active and branch instruction has a delay slot,
2543 // emit a NOP after it.
2544 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2545 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2546 createNop(true, IDLoc, Instructions);
2551 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2552 SmallVectorImpl<MCInst> &Instructions) {
2553 const MCOperand &DstRegOp = Inst.getOperand(0);
2554 assert(DstRegOp.isReg() && "expected register operand kind");
2556 const MCOperand &ImmOp = Inst.getOperand(1);
2557 assert(ImmOp.isImm() && "expected immediate operand kind");
2559 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2560 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2562 unsigned OpCode = 0;
2563 switch(Inst.getOpcode()) {
2571 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2575 int64_t ImmValue = ImmOp.getImm();
2577 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2580 warnIfNoMacro(IDLoc);
2582 unsigned ATReg = getATReg(IDLoc);
2586 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2587 IDLoc, Instructions))
2590 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2595 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2596 SmallVectorImpl<MCInst> &Instructions,
2597 bool isLoad, bool isImmOpnd) {
2598 unsigned ImmOffset, HiOffset, LoOffset;
2599 const MCExpr *ExprOffset;
2601 // 1st operand is either the source or destination register.
2602 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2603 unsigned RegOpNum = Inst.getOperand(0).getReg();
2604 // 2nd operand is the base register.
2605 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2606 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2607 // 3rd operand is either an immediate or expression.
2609 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2610 ImmOffset = Inst.getOperand(2).getImm();
2611 LoOffset = ImmOffset & 0x0000ffff;
2612 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2613 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2614 if (LoOffset & 0x8000)
2617 ExprOffset = Inst.getOperand(2).getExpr();
2618 // These are some of the types of expansions we perform here:
2619 // 1) lw $8, sym => lui $8, %hi(sym)
2620 // lw $8, %lo(sym)($8)
2621 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2623 // lw $8, %lo(offset)($9)
2624 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2626 // lw $8, %lo(offset)($at)
2627 // 4) sw $8, sym => lui $at, %hi(sym)
2628 // sw $8, %lo(sym)($at)
2629 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2631 // sw $8, %lo(offset)($at)
2632 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2633 // ldc1 $f0, %lo(sym)($at)
2635 // For load instructions we can use the destination register as a temporary
2636 // if base and dst are different (examples 1 and 2) and if the base register
2637 // is general purpose otherwise we must use $at (example 6) and error if it's
2638 // not available. For stores we must use $at (examples 4 and 5) because we
2639 // must not clobber the source register setting up the offset.
2640 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2641 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2642 unsigned RegClassIDOp0 =
2643 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2644 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2645 (RegClassIDOp0 == Mips::GPR64RegClassID);
2646 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2647 TmpRegNum = RegOpNum;
2649 // At this point we need AT to perform the expansions and we exit if it is
2651 TmpRegNum = getATReg(IDLoc);
2656 emitRX(Mips::LUi, TmpRegNum,
2657 isImmOpnd ? MCOperand::createImm(HiOffset)
2658 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2659 IDLoc, Instructions);
2660 // Add temp register to base.
2661 if (BaseRegNum != Mips::ZERO)
2662 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2663 // And finally, create original instruction with low part
2664 // of offset and new base.
2665 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2667 ? MCOperand::createImm(LoOffset)
2668 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2669 IDLoc, Instructions);
2673 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2674 SmallVectorImpl<MCInst> &Instructions) {
2675 unsigned OpNum = Inst.getNumOperands();
2676 unsigned Opcode = Inst.getOpcode();
2677 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2679 assert (Inst.getOperand(OpNum - 1).isImm() &&
2680 Inst.getOperand(OpNum - 2).isReg() &&
2681 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2683 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2684 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2685 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2686 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2687 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2688 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2689 // It can be implemented as SWM16 or LWM16 instruction.
2690 if (inMicroMipsMode() && hasMips32r6())
2691 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2693 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2696 Inst.setOpcode(NewOpcode);
2697 Instructions.push_back(Inst);
2701 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2702 SmallVectorImpl<MCInst> &Instructions) {
2703 bool EmittedNoMacroWarning = false;
2704 unsigned PseudoOpcode = Inst.getOpcode();
2705 unsigned SrcReg = Inst.getOperand(0).getReg();
2706 const MCOperand &TrgOp = Inst.getOperand(1);
2707 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2709 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2710 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2714 TrgReg = TrgOp.getReg();
2715 else if (TrgOp.isImm()) {
2716 warnIfNoMacro(IDLoc);
2717 EmittedNoMacroWarning = true;
2719 TrgReg = getATReg(IDLoc);
2723 switch(PseudoOpcode) {
2725 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2726 case Mips::BLTImmMacro:
2727 PseudoOpcode = Mips::BLT;
2729 case Mips::BLEImmMacro:
2730 PseudoOpcode = Mips::BLE;
2732 case Mips::BGEImmMacro:
2733 PseudoOpcode = Mips::BGE;
2735 case Mips::BGTImmMacro:
2736 PseudoOpcode = Mips::BGT;
2738 case Mips::BLTUImmMacro:
2739 PseudoOpcode = Mips::BLTU;
2741 case Mips::BLEUImmMacro:
2742 PseudoOpcode = Mips::BLEU;
2744 case Mips::BGEUImmMacro:
2745 PseudoOpcode = Mips::BGEU;
2747 case Mips::BGTUImmMacro:
2748 PseudoOpcode = Mips::BGTU;
2750 case Mips::BLTLImmMacro:
2751 PseudoOpcode = Mips::BLTL;
2753 case Mips::BLELImmMacro:
2754 PseudoOpcode = Mips::BLEL;
2756 case Mips::BGELImmMacro:
2757 PseudoOpcode = Mips::BGEL;
2759 case Mips::BGTLImmMacro:
2760 PseudoOpcode = Mips::BGTL;
2762 case Mips::BLTULImmMacro:
2763 PseudoOpcode = Mips::BLTUL;
2765 case Mips::BLEULImmMacro:
2766 PseudoOpcode = Mips::BLEUL;
2768 case Mips::BGEULImmMacro:
2769 PseudoOpcode = Mips::BGEUL;
2771 case Mips::BGTULImmMacro:
2772 PseudoOpcode = Mips::BGTUL;
2776 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2777 false, IDLoc, Instructions))
2781 switch (PseudoOpcode) {
2786 AcceptsEquality = false;
2787 ReverseOrderSLT = false;
2788 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2789 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2790 ZeroSrcOpcode = Mips::BGTZ;
2791 ZeroTrgOpcode = Mips::BLTZ;
2797 AcceptsEquality = true;
2798 ReverseOrderSLT = true;
2799 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2800 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2801 ZeroSrcOpcode = Mips::BGEZ;
2802 ZeroTrgOpcode = Mips::BLEZ;
2808 AcceptsEquality = true;
2809 ReverseOrderSLT = false;
2810 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2811 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2812 ZeroSrcOpcode = Mips::BLEZ;
2813 ZeroTrgOpcode = Mips::BGEZ;
2819 AcceptsEquality = false;
2820 ReverseOrderSLT = true;
2821 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2822 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2823 ZeroSrcOpcode = Mips::BLTZ;
2824 ZeroTrgOpcode = Mips::BGTZ;
2827 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2830 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2831 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2832 if (IsSrcRegZero && IsTrgRegZero) {
2833 // FIXME: All of these Opcode-specific if's are needed for compatibility
2834 // with GAS' behaviour. However, they may not generate the most efficient
2835 // code in some circumstances.
2836 if (PseudoOpcode == Mips::BLT) {
2837 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2841 if (PseudoOpcode == Mips::BLE) {
2842 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2844 Warning(IDLoc, "branch is always taken");
2847 if (PseudoOpcode == Mips::BGE) {
2848 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2850 Warning(IDLoc, "branch is always taken");
2853 if (PseudoOpcode == Mips::BGT) {
2854 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2858 if (PseudoOpcode == Mips::BGTU) {
2859 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2860 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2863 if (AcceptsEquality) {
2864 // If both registers are $0 and the pseudo-branch accepts equality, it
2865 // will always be taken, so we emit an unconditional branch.
2866 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2867 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2868 Warning(IDLoc, "branch is always taken");
2871 // If both registers are $0 and the pseudo-branch does not accept
2872 // equality, it will never be taken, so we don't have to emit anything.
2875 if (IsSrcRegZero || IsTrgRegZero) {
2876 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2877 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2878 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2879 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2880 // the pseudo-branch will never be taken, so we don't emit anything.
2881 // This only applies to unsigned pseudo-branches.
2884 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2885 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2886 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2887 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2888 // the pseudo-branch will always be taken, so we emit an unconditional
2890 // This only applies to unsigned pseudo-branches.
2891 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2892 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2893 Warning(IDLoc, "branch is always taken");
2897 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2898 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2899 // the pseudo-branch will be taken only when the non-zero register is
2900 // different from 0, so we emit a BNEZ.
2902 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2903 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2904 // the pseudo-branch will be taken only when the non-zero register is
2905 // equal to 0, so we emit a BEQZ.
2907 // Because only BLEU and BGEU branch on equality, we can use the
2908 // AcceptsEquality variable to decide when to emit the BEQZ.
2909 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2910 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2911 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2914 // If we have a signed pseudo-branch and one of the registers is $0,
2915 // we can use an appropriate compare-to-zero branch. We select which one
2916 // to use in the switch statement above.
2917 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2918 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2919 IDLoc, Instructions);
2923 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2924 // expansions. If it is not available, we return.
2925 unsigned ATRegNum = getATReg(IDLoc);
2929 if (!EmittedNoMacroWarning)
2930 warnIfNoMacro(IDLoc);
2932 // SLT fits well with 2 of our 4 pseudo-branches:
2933 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2934 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2935 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2936 // This is accomplished by using a BNEZ with the result of the SLT.
2938 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2939 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2940 // Because only BGE and BLE branch on equality, we can use the
2941 // AcceptsEquality variable to decide when to emit the BEQZ.
2942 // Note that the order of the SLT arguments doesn't change between
2945 // The same applies to the unsigned variants, except that SLTu is used
2947 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2948 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2949 IDLoc, Instructions);
2951 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2952 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2953 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2958 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2959 SmallVectorImpl<MCInst> &Instructions,
2960 const bool IsMips64, const bool Signed) {
2961 if (hasMips32r6()) {
2962 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2966 warnIfNoMacro(IDLoc);
2968 const MCOperand &RsRegOp = Inst.getOperand(0);
2969 assert(RsRegOp.isReg() && "expected register operand kind");
2970 unsigned RsReg = RsRegOp.getReg();
2972 const MCOperand &RtRegOp = Inst.getOperand(1);
2973 assert(RtRegOp.isReg() && "expected register operand kind");
2974 unsigned RtReg = RtRegOp.getReg();
2979 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2980 ZeroReg = Mips::ZERO_64;
2982 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2983 ZeroReg = Mips::ZERO;
2986 bool UseTraps = useTraps();
2988 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2989 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2990 Warning(IDLoc, "dividing zero by zero");
2992 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2994 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2998 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
3002 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
3007 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3008 Warning(IDLoc, "division by zero");
3011 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
3015 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
3020 // FIXME: The values for these two BranchTarget variables may be different in
3021 // micromips. These magic numbers need to be removed.
3022 unsigned BranchTargetNoTraps;
3023 unsigned BranchTarget;
3026 BranchTarget = IsMips64 ? 12 : 8;
3027 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
3029 BranchTarget = IsMips64 ? 20 : 16;
3030 BranchTargetNoTraps = 8;
3031 // Branch to the li instruction.
3032 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
3036 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
3039 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
3042 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3046 unsigned ATReg = getATReg(IDLoc);
3050 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
3052 // Branch to the mflo instruction.
3053 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3054 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
3055 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
3057 // Branch to the mflo instruction.
3058 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3059 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
3063 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
3065 // Branch to the mflo instruction.
3066 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
3067 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
3068 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
3070 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3074 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3075 SmallVectorImpl<MCInst> &Instructions) {
3076 if (hasMips32r6() || hasMips64r6()) {
3077 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3081 warnIfNoMacro(IDLoc);
3083 const MCOperand &DstRegOp = Inst.getOperand(0);
3084 assert(DstRegOp.isReg() && "expected register operand kind");
3086 const MCOperand &SrcRegOp = Inst.getOperand(1);
3087 assert(SrcRegOp.isReg() && "expected register operand kind");
3089 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3090 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3092 unsigned DstReg = DstRegOp.getReg();
3093 unsigned SrcReg = SrcRegOp.getReg();
3094 int64_t OffsetValue = OffsetImmOp.getImm();
3096 // NOTE: We always need AT for ULHU, as it is always used as the source
3097 // register for one of the LBu's.
3098 unsigned ATReg = getATReg(IDLoc);
3102 // When the value of offset+1 does not fit in 16 bits, we have to load the
3103 // offset in AT, (D)ADDu the original source register (if there was one), and
3104 // then use AT as the source register for the 2 generated LBu's.
3105 bool LoadedOffsetInAT = false;
3106 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3107 LoadedOffsetInAT = true;
3109 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3110 true, IDLoc, Instructions))
3113 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3114 // because it will make our output more similar to GAS'. For example,
3115 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3116 // instead of just an "ori $1, $9, 32768".
3117 // NOTE: If there is no source register specified in the ULHU, the parser
3118 // will interpret it as $0.
3119 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3120 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3123 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3124 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3125 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3127 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3129 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3130 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3132 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3133 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3136 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3138 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3139 FirstLbuOffset, IDLoc, Instructions);
3141 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3144 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3146 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3151 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3152 SmallVectorImpl<MCInst> &Instructions) {
3153 if (hasMips32r6() || hasMips64r6()) {
3154 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3158 const MCOperand &DstRegOp = Inst.getOperand(0);
3159 assert(DstRegOp.isReg() && "expected register operand kind");
3161 const MCOperand &SrcRegOp = Inst.getOperand(1);
3162 assert(SrcRegOp.isReg() && "expected register operand kind");
3164 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3165 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3167 unsigned SrcReg = SrcRegOp.getReg();
3168 int64_t OffsetValue = OffsetImmOp.getImm();
3171 // When the value of offset+3 does not fit in 16 bits, we have to load the
3172 // offset in AT, (D)ADDu the original source register (if there was one), and
3173 // then use AT as the source register for the generated LWL and LWR.
3174 bool LoadedOffsetInAT = false;
3175 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3176 ATReg = getATReg(IDLoc);
3179 LoadedOffsetInAT = true;
3181 warnIfNoMacro(IDLoc);
3183 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3184 true, IDLoc, Instructions))
3187 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3188 // because it will make our output more similar to GAS'. For example,
3189 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3190 // instead of just an "ori $1, $9, 32768".
3191 // NOTE: If there is no source register specified in the ULW, the parser
3192 // will interpret it as $0.
3193 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3194 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3197 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3198 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3200 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3201 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3203 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3204 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3207 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3210 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3216 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3217 SmallVectorImpl<MCInst> &Instructions) {
3219 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3220 assert (Inst.getOperand(0).isReg() &&
3221 Inst.getOperand(1).isReg() &&
3222 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3224 unsigned ATReg = Mips::NoRegister;
3225 unsigned FinalDstReg = Mips::NoRegister;
3226 unsigned DstReg = Inst.getOperand(0).getReg();
3227 unsigned SrcReg = Inst.getOperand(1).getReg();
3228 int64_t ImmValue = Inst.getOperand(2).getImm();
3230 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3232 unsigned FinalOpcode = Inst.getOpcode();
3234 if (DstReg == SrcReg) {
3235 ATReg = getATReg(Inst.getLoc());
3238 FinalDstReg = DstReg;
3242 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3243 switch (FinalOpcode) {
3245 llvm_unreachable("unimplemented expansion");
3247 FinalOpcode = Mips::ADD;
3250 FinalOpcode = Mips::ADDu;
3253 FinalOpcode = Mips::AND;
3255 case (Mips::NORImm):
3256 FinalOpcode = Mips::NOR;
3259 FinalOpcode = Mips::OR;
3262 FinalOpcode = Mips::SLT;
3265 FinalOpcode = Mips::SLTu;
3268 FinalOpcode = Mips::XOR;
3272 if (FinalDstReg == Mips::NoRegister)
3273 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3275 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3282 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc,
3283 SmallVectorImpl<MCInst> &Instructions) {
3284 unsigned ATReg = Mips::NoRegister;
3285 unsigned DReg = Inst.getOperand(0).getReg();
3286 unsigned SReg = Inst.getOperand(1).getReg();
3287 unsigned TReg = Inst.getOperand(2).getReg();
3288 unsigned TmpReg = DReg;
3290 unsigned FirstShift = Mips::NOP;
3291 unsigned SecondShift = Mips::NOP;
3293 if (hasMips32r2()) {
3296 TmpReg = getATReg(Inst.getLoc());
3301 if (Inst.getOpcode() == Mips::ROL) {
3302 emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3303 emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Instructions);
3307 if (Inst.getOpcode() == Mips::ROR) {
3308 emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3317 switch (Inst.getOpcode()) {
3319 llvm_unreachable("unexpected instruction opcode");
3321 FirstShift = Mips::SRLV;
3322 SecondShift = Mips::SLLV;
3325 FirstShift = Mips::SLLV;
3326 SecondShift = Mips::SRLV;
3330 ATReg = getATReg(Inst.getLoc());
3334 emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3335 emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Instructions);
3336 emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3337 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3345 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3346 SmallVectorImpl<MCInst> &Instructions) {
3348 unsigned ATReg = Mips::NoRegister;
3349 unsigned DReg = Inst.getOperand(0).getReg();
3350 unsigned SReg = Inst.getOperand(1).getReg();
3351 int64_t ImmValue = Inst.getOperand(2).getImm();
3353 unsigned FirstShift = Mips::NOP;
3354 unsigned SecondShift = Mips::NOP;
3356 if (hasMips32r2()) {
3358 if (Inst.getOpcode() == Mips::ROLImm) {
3359 uint64_t MaxShift = 32;
3360 uint64_t ShiftValue = ImmValue;
3362 ShiftValue = MaxShift - ImmValue;
3363 emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), Instructions);
3367 if (Inst.getOpcode() == Mips::RORImm) {
3368 emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), Instructions);
3377 if (ImmValue == 0) {
3378 emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), Instructions);
3382 switch (Inst.getOpcode()) {
3384 llvm_unreachable("unexpected instruction opcode");
3386 FirstShift = Mips::SLL;
3387 SecondShift = Mips::SRL;
3390 FirstShift = Mips::SRL;
3391 SecondShift = Mips::SLL;
3395 ATReg = getATReg(Inst.getLoc());
3399 emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), Instructions);
3400 emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), Instructions);
3401 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3409 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc,
3410 SmallVectorImpl<MCInst> &Instructions) {
3412 unsigned ATReg = Mips::NoRegister;
3413 unsigned DReg = Inst.getOperand(0).getReg();
3414 unsigned SReg = Inst.getOperand(1).getReg();
3415 unsigned TReg = Inst.getOperand(2).getReg();
3416 unsigned TmpReg = DReg;
3418 unsigned FirstShift = Mips::NOP;
3419 unsigned SecondShift = Mips::NOP;
3421 if (hasMips64r2()) {
3423 if (TmpReg == SReg) {
3424 TmpReg = getATReg(Inst.getLoc());
3429 if (Inst.getOpcode() == Mips::DROL) {
3430 emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3431 emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Instructions);
3435 if (Inst.getOpcode() == Mips::DROR) {
3436 emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3445 switch (Inst.getOpcode()) {
3447 llvm_unreachable("unexpected instruction opcode");
3449 FirstShift = Mips::DSRLV;
3450 SecondShift = Mips::DSLLV;
3453 FirstShift = Mips::DSLLV;
3454 SecondShift = Mips::DSRLV;
3458 ATReg = getATReg(Inst.getLoc());
3462 emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3463 emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Instructions);
3464 emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3465 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3473 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
3474 SmallVectorImpl<MCInst> &Instructions) {
3476 unsigned ATReg = Mips::NoRegister;
3477 unsigned DReg = Inst.getOperand(0).getReg();
3478 unsigned SReg = Inst.getOperand(1).getReg();
3479 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
3481 unsigned FirstShift = Mips::NOP;
3482 unsigned SecondShift = Mips::NOP;
3486 if (hasMips64r2()) {
3488 unsigned FinalOpcode = Mips::NOP;
3490 FinalOpcode = Mips::DROTR;
3491 else if (ImmValue % 32 == 0)
3492 FinalOpcode = Mips::DROTR32;
3493 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3494 if (Inst.getOpcode() == Mips::DROLImm)
3495 FinalOpcode = Mips::DROTR32;
3497 FinalOpcode = Mips::DROTR;
3498 } else if (ImmValue >= 33) {
3499 if (Inst.getOpcode() == Mips::DROLImm)
3500 FinalOpcode = Mips::DROTR;
3502 FinalOpcode = Mips::DROTR32;
3505 uint64_t ShiftValue = ImmValue % 32;
3506 if (Inst.getOpcode() == Mips::DROLImm)
3507 ShiftValue = (32 - ImmValue % 32) % 32;
3509 emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), Instructions);
3516 if (ImmValue == 0) {
3517 emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), Instructions);
3521 switch (Inst.getOpcode()) {
3523 llvm_unreachable("unexpected instruction opcode");
3525 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3526 FirstShift = Mips::DSLL;
3527 SecondShift = Mips::DSRL32;
3529 if (ImmValue == 32) {
3530 FirstShift = Mips::DSLL32;
3531 SecondShift = Mips::DSRL32;
3533 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3534 FirstShift = Mips::DSLL32;
3535 SecondShift = Mips::DSRL;
3539 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3540 FirstShift = Mips::DSRL;
3541 SecondShift = Mips::DSLL32;
3543 if (ImmValue == 32) {
3544 FirstShift = Mips::DSRL32;
3545 SecondShift = Mips::DSLL32;
3547 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3548 FirstShift = Mips::DSRL32;
3549 SecondShift = Mips::DSLL;
3554 ATReg = getATReg(Inst.getLoc());
3558 emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), Instructions);
3559 emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32, Inst.getLoc(), Instructions);
3560 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3568 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3569 SmallVectorImpl<MCInst> &Instructions) {
3570 if (hasShortDelaySlot)
3571 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3573 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3576 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3577 unsigned TrgReg, bool Is64Bit,
3578 SmallVectorImpl<MCInst> &Instructions) {
3579 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3583 void MipsAsmParser::createCpRestoreMemOp(
3584 bool IsLoad, int StackOffset, SMLoc IDLoc,
3585 SmallVectorImpl<MCInst> &Instructions) {
3586 // If the offset can not fit into 16 bits, we need to expand.
3587 if (!isInt<16>(StackOffset)) {
3589 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3590 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3591 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3592 MemInst.addOperand(MCOperand::createImm(StackOffset));
3593 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3597 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3601 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3602 // As described by the Mips32r2 spec, the registers Rd and Rs for
3603 // jalr.hb must be different.
3604 unsigned Opcode = Inst.getOpcode();
3606 if (Opcode == Mips::JALR_HB &&
3607 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3608 return Match_RequiresDifferentSrcAndDst;
3610 return Match_Success;
3613 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3614 uint64_t ErrorInfo) {
3615 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3616 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3617 if (ErrorLoc == SMLoc())
3624 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3625 OperandVector &Operands,
3627 uint64_t &ErrorInfo,
3628 bool MatchingInlineAsm) {
3631 SmallVector<MCInst, 8> Instructions;
3632 unsigned MatchResult =
3633 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3635 switch (MatchResult) {
3636 case Match_Success: {
3637 if (processInstruction(Inst, IDLoc, Instructions))
3639 for (unsigned i = 0; i < Instructions.size(); i++)
3640 Out.EmitInstruction(Instructions[i], getSTI());
3643 case Match_MissingFeature:
3644 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3646 case Match_InvalidOperand: {
3647 SMLoc ErrorLoc = IDLoc;
3648 if (ErrorInfo != ~0ULL) {
3649 if (ErrorInfo >= Operands.size())
3650 return Error(IDLoc, "too few operands for instruction");
3652 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3653 if (ErrorLoc == SMLoc())
3657 return Error(ErrorLoc, "invalid operand for instruction");
3659 case Match_MnemonicFail:
3660 return Error(IDLoc, "invalid instruction");
3661 case Match_RequiresDifferentSrcAndDst:
3662 return Error(IDLoc, "source and destination must be different");
3664 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3666 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3667 "expected 1-bit unsigned immediate");
3669 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3670 "expected 2-bit unsigned immediate");
3672 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3673 "expected immediate in range 1 .. 4");
3675 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3676 "expected 3-bit unsigned immediate");
3678 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3679 "expected 4-bit unsigned immediate");
3682 llvm_unreachable("Implement any new match types added!");
3685 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3686 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3687 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3688 ") without \".set noat\"");
3691 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3692 if (!AssemblerOptions.back()->isMacro())
3693 Warning(Loc, "macro instruction expanded into multiple instructions");
3697 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3698 SMRange Range, bool ShowColors) {
3699 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3700 Range, SMFixIt(Range, FixMsg),
3704 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3707 CC = StringSwitch<unsigned>(Name)
3743 if (!(isABI_N32() || isABI_N64()))
3746 if (12 <= CC && CC <= 15) {
3747 // Name is one of t4-t7
3748 AsmToken RegTok = getLexer().peekTok();
3749 SMRange RegRange = RegTok.getLocRange();
3751 StringRef FixedName = StringSwitch<StringRef>(Name)
3757 assert(FixedName != "" && "Register name is not one of t4-t7.");
3759 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3760 "Did you mean $" + FixedName + "?", RegRange);
3763 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3764 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3765 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3766 if (8 <= CC && CC <= 11)
3770 CC = StringSwitch<unsigned>(Name)
3782 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3785 CC = StringSwitch<unsigned>(Name)
3786 .Case("hwr_cpunum", 0)
3787 .Case("hwr_synci_step", 1)
3789 .Case("hwr_ccres", 3)
3790 .Case("hwr_ulr", 29)
3796 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3798 if (Name[0] == 'f') {
3799 StringRef NumString = Name.substr(1);
3801 if (NumString.getAsInteger(10, IntVal))
3802 return -1; // This is not an integer.
3803 if (IntVal > 31) // Maximum index for fpu register.
3810 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3812 if (Name.startswith("fcc")) {
3813 StringRef NumString = Name.substr(3);
3815 if (NumString.getAsInteger(10, IntVal))
3816 return -1; // This is not an integer.
3817 if (IntVal > 7) // There are only 8 fcc registers.
3824 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3826 if (Name.startswith("ac")) {
3827 StringRef NumString = Name.substr(2);
3829 if (NumString.getAsInteger(10, IntVal))
3830 return -1; // This is not an integer.
3831 if (IntVal > 3) // There are only 3 acc registers.
3838 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3841 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3850 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3853 CC = StringSwitch<unsigned>(Name)
3856 .Case("msaaccess", 2)
3858 .Case("msamodify", 4)
3859 .Case("msarequest", 5)
3861 .Case("msaunmap", 7)
3867 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3868 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3870 reportParseError(Loc,
3871 "pseudo-instruction requires $at, which is not available");
3874 unsigned AT = getReg(
3875 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3879 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3880 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3883 unsigned MipsAsmParser::getGPR(int RegNo) {
3884 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3888 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3890 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3893 return getReg(RegClass, RegNum);
3896 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3897 MCAsmParser &Parser = getParser();
3898 DEBUG(dbgs() << "parseOperand\n");
3900 // Check if the current operand has a custom associated parser, if so, try to
3901 // custom parse the operand, or fallback to the general approach.
3902 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3903 if (ResTy == MatchOperand_Success)
3905 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3906 // there was a match, but an error occurred, in which case, just return that
3907 // the operand parsing failed.
3908 if (ResTy == MatchOperand_ParseFail)
3911 DEBUG(dbgs() << ".. Generic Parser\n");
3913 switch (getLexer().getKind()) {
3915 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3917 case AsmToken::Dollar: {
3918 // Parse the register.
3919 SMLoc S = Parser.getTok().getLoc();
3921 // Almost all registers have been parsed by custom parsers. There is only
3922 // one exception to this. $zero (and it's alias $0) will reach this point
3923 // for div, divu, and similar instructions because it is not an operand
3924 // to the instruction definition but an explicit register. Special case
3925 // this situation for now.
3926 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3929 // Maybe it is a symbol reference.
3930 StringRef Identifier;
3931 if (Parser.parseIdentifier(Identifier))
3934 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3935 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3936 // Otherwise create a symbol reference.
3938 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3940 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3943 // Else drop to expression parsing.
3944 case AsmToken::LParen:
3945 case AsmToken::Minus:
3946 case AsmToken::Plus:
3947 case AsmToken::Integer:
3948 case AsmToken::Tilde:
3949 case AsmToken::String: {
3950 DEBUG(dbgs() << ".. generic integer\n");
3951 OperandMatchResultTy ResTy = parseImm(Operands);
3952 return ResTy != MatchOperand_Success;
3954 case AsmToken::Percent: {
3955 // It is a symbol reference or constant expression.
3956 const MCExpr *IdVal;
3957 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3958 if (parseRelocOperand(IdVal))
3961 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3963 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3965 } // case AsmToken::Percent
3966 } // switch(getLexer().getKind())
3970 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3971 StringRef RelocStr) {
3973 // Check the type of the expression.
3974 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3975 // It's a constant, evaluate reloc value.
3977 switch (getVariantKind(RelocStr)) {
3978 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3979 // Get the 1st 16-bits.
3980 Val = MCE->getValue() & 0xffff;
3982 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3983 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3984 // 16 bits being negative.
3985 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3987 case MCSymbolRefExpr::VK_Mips_HIGHER:
3988 // Get the 3rd 16-bits.
3989 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3991 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3992 // Get the 4th 16-bits.
3993 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3996 report_fatal_error("unsupported reloc value");
3998 return MCConstantExpr::create(Val, getContext());
4001 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
4002 // It's a symbol, create a symbolic expression from the symbol.
4003 const MCSymbol *Symbol = &MSRE->getSymbol();
4004 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
4005 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
4009 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4010 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
4012 // Try to create target expression.
4013 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
4014 return MipsMCExpr::create(VK, Expr, getContext());
4016 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
4017 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
4018 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
4022 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
4023 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
4024 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
4027 // Just return the original expression.
4031 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
4033 switch (Expr->getKind()) {
4034 case MCExpr::Constant:
4036 case MCExpr::SymbolRef:
4037 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
4038 case MCExpr::Binary:
4039 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4040 if (!isEvaluated(BE->getLHS()))
4042 return isEvaluated(BE->getRHS());
4045 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
4046 case MCExpr::Target:
4052 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
4053 MCAsmParser &Parser = getParser();
4054 Parser.Lex(); // Eat the % token.
4055 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
4056 if (Tok.isNot(AsmToken::Identifier))
4059 std::string Str = Tok.getIdentifier();
4061 Parser.Lex(); // Eat the identifier.
4062 // Now make an expression from the rest of the operand.
4063 const MCExpr *IdVal;
4066 if (getLexer().getKind() == AsmToken::LParen) {
4068 Parser.Lex(); // Eat the '(' token.
4069 if (getLexer().getKind() == AsmToken::Percent) {
4070 Parser.Lex(); // Eat the % token.
4071 const AsmToken &nextTok = Parser.getTok();
4072 if (nextTok.isNot(AsmToken::Identifier))
4075 Str += nextTok.getIdentifier();
4076 Parser.Lex(); // Eat the identifier.
4077 if (getLexer().getKind() != AsmToken::LParen)
4082 if (getParser().parseParenExpression(IdVal, EndLoc))
4085 while (getLexer().getKind() == AsmToken::RParen)
4086 Parser.Lex(); // Eat the ')' token.
4089 return true; // Parenthesis must follow the relocation operand.
4091 Res = evaluateRelocExpr(IdVal, Str);
4095 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
4097 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
4098 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4099 if (ResTy == MatchOperand_Success) {
4100 assert(Operands.size() == 1);
4101 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
4102 StartLoc = Operand.getStartLoc();
4103 EndLoc = Operand.getEndLoc();
4105 // AFAIK, we only support numeric registers and named GPR's in CFI
4107 // Don't worry about eating tokens before failing. Using an unrecognised
4108 // register is a parse error.
4109 if (Operand.isGPRAsmReg()) {
4110 // Resolve to GPR32 or GPR64 appropriately.
4111 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
4114 return (RegNo == (unsigned)-1);
4117 assert(Operands.size() == 0);
4118 return (RegNo == (unsigned)-1);
4121 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
4122 MCAsmParser &Parser = getParser();
4125 unsigned NumOfLParen = 0;
4127 while (getLexer().getKind() == AsmToken::LParen) {
4132 switch (getLexer().getKind()) {
4135 case AsmToken::Identifier:
4136 case AsmToken::LParen:
4137 case AsmToken::Integer:
4138 case AsmToken::Minus:
4139 case AsmToken::Plus:
4141 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
4143 Result = (getParser().parseExpression(Res));
4144 while (getLexer().getKind() == AsmToken::RParen)
4147 case AsmToken::Percent:
4148 Result = parseRelocOperand(Res);
4153 MipsAsmParser::OperandMatchResultTy
4154 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
4155 MCAsmParser &Parser = getParser();
4156 DEBUG(dbgs() << "parseMemOperand\n");
4157 const MCExpr *IdVal = nullptr;
4159 bool isParenExpr = false;
4160 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
4161 // First operand is the offset.
4162 S = Parser.getTok().getLoc();
4164 if (getLexer().getKind() == AsmToken::LParen) {
4169 if (getLexer().getKind() != AsmToken::Dollar) {
4170 if (parseMemOffset(IdVal, isParenExpr))
4171 return MatchOperand_ParseFail;
4173 const AsmToken &Tok = Parser.getTok(); // Get the next token.
4174 if (Tok.isNot(AsmToken::LParen)) {
4175 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
4176 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
4178 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4179 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4180 return MatchOperand_Success;
4182 if (Tok.is(AsmToken::EndOfStatement)) {
4184 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4186 // Zero register assumed, add a memory operand with ZERO as its base.
4187 // "Base" will be managed by k_Memory.
4188 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
4191 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
4192 return MatchOperand_Success;
4194 Error(Parser.getTok().getLoc(), "'(' expected");
4195 return MatchOperand_ParseFail;
4198 Parser.Lex(); // Eat the '(' token.
4201 Res = parseAnyRegister(Operands);
4202 if (Res != MatchOperand_Success)
4205 if (Parser.getTok().isNot(AsmToken::RParen)) {
4206 Error(Parser.getTok().getLoc(), "')' expected");
4207 return MatchOperand_ParseFail;
4210 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4212 Parser.Lex(); // Eat the ')' token.
4215 IdVal = MCConstantExpr::create(0, getContext());
4217 // Replace the register operand with the memory operand.
4218 std::unique_ptr<MipsOperand> op(
4219 static_cast<MipsOperand *>(Operands.back().release()));
4220 // Remove the register from the operands.
4221 // "op" will be managed by k_Memory.
4222 Operands.pop_back();
4223 // Add the memory operand.
4224 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
4226 if (IdVal->evaluateAsAbsolute(Imm))
4227 IdVal = MCConstantExpr::create(Imm, getContext());
4228 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
4229 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
4233 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
4234 return MatchOperand_Success;
4237 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
4238 MCAsmParser &Parser = getParser();
4239 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
4241 SMLoc S = Parser.getTok().getLoc();
4243 if (Sym->isVariable())
4244 Expr = Sym->getVariableValue();
4247 if (Expr->getKind() == MCExpr::SymbolRef) {
4248 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4249 StringRef DefSymbol = Ref->getSymbol().getName();
4250 if (DefSymbol.startswith("$")) {
4251 OperandMatchResultTy ResTy =
4252 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
4253 if (ResTy == MatchOperand_Success) {
4256 } else if (ResTy == MatchOperand_ParseFail)
4257 llvm_unreachable("Should never ParseFail");
4260 } else if (Expr->getKind() == MCExpr::Constant) {
4262 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
4264 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
4271 MipsAsmParser::OperandMatchResultTy
4272 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
4273 StringRef Identifier,
4275 int Index = matchCPURegisterName(Identifier);
4277 Operands.push_back(MipsOperand::createGPRReg(
4278 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4279 return MatchOperand_Success;
4282 Index = matchHWRegsRegisterName(Identifier);
4284 Operands.push_back(MipsOperand::createHWRegsReg(
4285 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4286 return MatchOperand_Success;
4289 Index = matchFPURegisterName(Identifier);
4291 Operands.push_back(MipsOperand::createFGRReg(
4292 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4293 return MatchOperand_Success;
4296 Index = matchFCCRegisterName(Identifier);
4298 Operands.push_back(MipsOperand::createFCCReg(
4299 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4300 return MatchOperand_Success;
4303 Index = matchACRegisterName(Identifier);
4305 Operands.push_back(MipsOperand::createACCReg(
4306 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4307 return MatchOperand_Success;
4310 Index = matchMSA128RegisterName(Identifier);
4312 Operands.push_back(MipsOperand::createMSA128Reg(
4313 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4314 return MatchOperand_Success;
4317 Index = matchMSA128CtrlRegisterName(Identifier);
4319 Operands.push_back(MipsOperand::createMSACtrlReg(
4320 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4321 return MatchOperand_Success;
4324 return MatchOperand_NoMatch;
4327 MipsAsmParser::OperandMatchResultTy
4328 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
4329 MCAsmParser &Parser = getParser();
4330 auto Token = Parser.getLexer().peekTok(false);
4332 if (Token.is(AsmToken::Identifier)) {
4333 DEBUG(dbgs() << ".. identifier\n");
4334 StringRef Identifier = Token.getIdentifier();
4335 OperandMatchResultTy ResTy =
4336 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4338 } else if (Token.is(AsmToken::Integer)) {
4339 DEBUG(dbgs() << ".. integer\n");
4340 Operands.push_back(MipsOperand::createNumericReg(
4341 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
4343 return MatchOperand_Success;
4346 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4348 return MatchOperand_NoMatch;
4351 MipsAsmParser::OperandMatchResultTy
4352 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4353 MCAsmParser &Parser = getParser();
4354 DEBUG(dbgs() << "parseAnyRegister\n");
4356 auto Token = Parser.getTok();
4358 SMLoc S = Token.getLoc();
4360 if (Token.isNot(AsmToken::Dollar)) {
4361 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4362 if (Token.is(AsmToken::Identifier)) {
4363 if (searchSymbolAlias(Operands))
4364 return MatchOperand_Success;
4366 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4367 return MatchOperand_NoMatch;
4369 DEBUG(dbgs() << ".. $\n");
4371 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4372 if (ResTy == MatchOperand_Success) {
4374 Parser.Lex(); // identifier
4379 MipsAsmParser::OperandMatchResultTy
4380 MipsAsmParser::parseImm(OperandVector &Operands) {
4381 MCAsmParser &Parser = getParser();
4382 switch (getLexer().getKind()) {
4384 return MatchOperand_NoMatch;
4385 case AsmToken::LParen:
4386 case AsmToken::Minus:
4387 case AsmToken::Plus:
4388 case AsmToken::Integer:
4389 case AsmToken::Tilde:
4390 case AsmToken::String:
4394 const MCExpr *IdVal;
4395 SMLoc S = Parser.getTok().getLoc();
4396 if (getParser().parseExpression(IdVal))
4397 return MatchOperand_ParseFail;
4399 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4400 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4401 return MatchOperand_Success;
4404 MipsAsmParser::OperandMatchResultTy
4405 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4406 MCAsmParser &Parser = getParser();
4407 DEBUG(dbgs() << "parseJumpTarget\n");
4409 SMLoc S = getLexer().getLoc();
4411 // Integers and expressions are acceptable
4412 OperandMatchResultTy ResTy = parseImm(Operands);
4413 if (ResTy != MatchOperand_NoMatch)
4416 // Registers are a valid target and have priority over symbols.
4417 ResTy = parseAnyRegister(Operands);
4418 if (ResTy != MatchOperand_NoMatch)
4421 const MCExpr *Expr = nullptr;
4422 if (Parser.parseExpression(Expr)) {
4423 // We have no way of knowing if a symbol was consumed so we must ParseFail
4424 return MatchOperand_ParseFail;
4427 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4428 return MatchOperand_Success;
4431 MipsAsmParser::OperandMatchResultTy
4432 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4433 MCAsmParser &Parser = getParser();
4434 const MCExpr *IdVal;
4435 // If the first token is '$' we may have register operand.
4436 if (Parser.getTok().is(AsmToken::Dollar))
4437 return MatchOperand_NoMatch;
4438 SMLoc S = Parser.getTok().getLoc();
4439 if (getParser().parseExpression(IdVal))
4440 return MatchOperand_ParseFail;
4441 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4442 assert(MCE && "Unexpected MCExpr type.");
4443 int64_t Val = MCE->getValue();
4444 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4445 Operands.push_back(MipsOperand::CreateImm(
4446 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4447 return MatchOperand_Success;
4450 MipsAsmParser::OperandMatchResultTy
4451 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4452 MCAsmParser &Parser = getParser();
4453 switch (getLexer().getKind()) {
4455 return MatchOperand_NoMatch;
4456 case AsmToken::LParen:
4457 case AsmToken::Plus:
4458 case AsmToken::Minus:
4459 case AsmToken::Integer:
4464 SMLoc S = Parser.getTok().getLoc();
4466 if (getParser().parseExpression(Expr))
4467 return MatchOperand_ParseFail;
4470 if (!Expr->evaluateAsAbsolute(Val)) {
4471 Error(S, "expected immediate value");
4472 return MatchOperand_ParseFail;
4475 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4476 // and because the CPU always adds one to the immediate field, the allowed
4477 // range becomes 1..4. We'll only check the range here and will deal
4478 // with the addition/subtraction when actually decoding/encoding
4480 if (Val < 1 || Val > 4) {
4481 Error(S, "immediate not in range (1..4)");
4482 return MatchOperand_ParseFail;
4486 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4487 return MatchOperand_Success;
4490 MipsAsmParser::OperandMatchResultTy
4491 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4492 MCAsmParser &Parser = getParser();
4493 SmallVector<unsigned, 10> Regs;
4495 unsigned PrevReg = Mips::NoRegister;
4496 bool RegRange = false;
4497 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4499 if (Parser.getTok().isNot(AsmToken::Dollar))
4500 return MatchOperand_ParseFail;
4502 SMLoc S = Parser.getTok().getLoc();
4503 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4504 SMLoc E = getLexer().getLoc();
4505 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4506 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4508 // Remove last register operand because registers from register range
4509 // should be inserted first.
4510 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4511 (!isGP64bit() && RegNo == Mips::RA)) {
4512 Regs.push_back(RegNo);
4514 unsigned TmpReg = PrevReg + 1;
4515 while (TmpReg <= RegNo) {
4516 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4517 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4519 Error(E, "invalid register operand");
4520 return MatchOperand_ParseFail;
4524 Regs.push_back(TmpReg++);
4530 if ((PrevReg == Mips::NoRegister) &&
4531 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
4532 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
4533 Error(E, "$16 or $31 expected");
4534 return MatchOperand_ParseFail;
4535 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
4536 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
4538 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
4539 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
4541 Error(E, "invalid register operand");
4542 return MatchOperand_ParseFail;
4543 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4544 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
4545 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
4547 Error(E, "consecutive register numbers expected");
4548 return MatchOperand_ParseFail;
4551 Regs.push_back(RegNo);
4554 if (Parser.getTok().is(AsmToken::Minus))
4557 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4558 !Parser.getTok().isNot(AsmToken::Comma)) {
4559 Error(E, "',' or '-' expected");
4560 return MatchOperand_ParseFail;
4563 Lex(); // Consume comma or minus
4564 if (Parser.getTok().isNot(AsmToken::Dollar))
4570 SMLoc E = Parser.getTok().getLoc();
4571 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4572 parseMemOperand(Operands);
4573 return MatchOperand_Success;
4576 MipsAsmParser::OperandMatchResultTy
4577 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4578 MCAsmParser &Parser = getParser();
4580 SMLoc S = Parser.getTok().getLoc();
4581 if (parseAnyRegister(Operands) != MatchOperand_Success)
4582 return MatchOperand_ParseFail;
4584 SMLoc E = Parser.getTok().getLoc();
4585 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4586 unsigned Reg = Op.getGPR32Reg();
4587 Operands.pop_back();
4588 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4589 return MatchOperand_Success;
4592 MipsAsmParser::OperandMatchResultTy
4593 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4594 MCAsmParser &Parser = getParser();
4595 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4596 SmallVector<unsigned, 10> Regs;
4598 if (Parser.getTok().isNot(AsmToken::Dollar))
4599 return MatchOperand_ParseFail;
4601 SMLoc S = Parser.getTok().getLoc();
4603 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4604 return MatchOperand_ParseFail;
4606 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4607 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4608 Regs.push_back(RegNo);
4610 SMLoc E = Parser.getTok().getLoc();
4611 if (Parser.getTok().isNot(AsmToken::Comma)) {
4612 Error(E, "',' expected");
4613 return MatchOperand_ParseFail;
4619 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4620 return MatchOperand_ParseFail;
4622 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4623 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4624 Regs.push_back(RegNo);
4626 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4628 return MatchOperand_Success;
4631 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4633 MCSymbolRefExpr::VariantKind VK =
4634 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4635 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4636 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4637 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4638 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4639 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4640 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4641 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4642 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4643 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4644 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4645 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4646 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4647 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4648 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4649 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4650 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4651 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4652 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4653 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4654 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4655 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4656 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4657 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4658 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4659 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4660 .Default(MCSymbolRefExpr::VK_None);
4662 assert(VK != MCSymbolRefExpr::VK_None);
4667 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4669 /// ::= '(', register, ')'
4670 /// handle it before we iterate so we don't get tripped up by the lack of
4672 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4673 MCAsmParser &Parser = getParser();
4674 if (getLexer().is(AsmToken::LParen)) {
4676 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4678 if (parseOperand(Operands, Name)) {
4679 SMLoc Loc = getLexer().getLoc();
4680 Parser.eatToEndOfStatement();
4681 return Error(Loc, "unexpected token in argument list");
4683 if (Parser.getTok().isNot(AsmToken::RParen)) {
4684 SMLoc Loc = getLexer().getLoc();
4685 Parser.eatToEndOfStatement();
4686 return Error(Loc, "unexpected token, expected ')'");
4689 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4695 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4696 /// either one of these.
4697 /// ::= '[', register, ']'
4698 /// ::= '[', integer, ']'
4699 /// handle it before we iterate so we don't get tripped up by the lack of
4701 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4702 OperandVector &Operands) {
4703 MCAsmParser &Parser = getParser();
4704 if (getLexer().is(AsmToken::LBrac)) {
4706 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4708 if (parseOperand(Operands, Name)) {
4709 SMLoc Loc = getLexer().getLoc();
4710 Parser.eatToEndOfStatement();
4711 return Error(Loc, "unexpected token in argument list");
4713 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4714 SMLoc Loc = getLexer().getLoc();
4715 Parser.eatToEndOfStatement();
4716 return Error(Loc, "unexpected token, expected ']'");
4719 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4725 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4726 SMLoc NameLoc, OperandVector &Operands) {
4727 MCAsmParser &Parser = getParser();
4728 DEBUG(dbgs() << "ParseInstruction\n");
4730 // We have reached first instruction, module directive are now forbidden.
4731 getTargetStreamer().forbidModuleDirective();
4733 // Check if we have valid mnemonic
4734 if (!mnemonicIsValid(Name, 0)) {
4735 Parser.eatToEndOfStatement();
4736 return Error(NameLoc, "unknown instruction");
4738 // First operand in MCInst is instruction mnemonic.
4739 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4741 // Read the remaining operands.
4742 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4743 // Read the first operand.
4744 if (parseOperand(Operands, Name)) {
4745 SMLoc Loc = getLexer().getLoc();
4746 Parser.eatToEndOfStatement();
4747 return Error(Loc, "unexpected token in argument list");
4749 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4751 // AFAIK, parenthesis suffixes are never on the first operand
4753 while (getLexer().is(AsmToken::Comma)) {
4754 Parser.Lex(); // Eat the comma.
4755 // Parse and remember the operand.
4756 if (parseOperand(Operands, Name)) {
4757 SMLoc Loc = getLexer().getLoc();
4758 Parser.eatToEndOfStatement();
4759 return Error(Loc, "unexpected token in argument list");
4761 // Parse bracket and parenthesis suffixes before we iterate
4762 if (getLexer().is(AsmToken::LBrac)) {
4763 if (parseBracketSuffix(Name, Operands))
4765 } else if (getLexer().is(AsmToken::LParen) &&
4766 parseParenSuffix(Name, Operands))
4770 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4771 SMLoc Loc = getLexer().getLoc();
4772 Parser.eatToEndOfStatement();
4773 return Error(Loc, "unexpected token in argument list");
4775 Parser.Lex(); // Consume the EndOfStatement.
4779 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4780 MCAsmParser &Parser = getParser();
4781 SMLoc Loc = getLexer().getLoc();
4782 Parser.eatToEndOfStatement();
4783 return Error(Loc, ErrorMsg);
4786 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4787 return Error(Loc, ErrorMsg);
4790 bool MipsAsmParser::parseSetNoAtDirective() {
4791 MCAsmParser &Parser = getParser();
4792 // Line should look like: ".set noat".
4794 // Set the $at register to $0.
4795 AssemblerOptions.back()->setATRegIndex(0);
4797 Parser.Lex(); // Eat "noat".
4799 // If this is not the end of the statement, report an error.
4800 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4801 reportParseError("unexpected token, expected end of statement");
4805 getTargetStreamer().emitDirectiveSetNoAt();
4806 Parser.Lex(); // Consume the EndOfStatement.
4810 bool MipsAsmParser::parseSetAtDirective() {
4811 // Line can be: ".set at", which sets $at to $1
4812 // or ".set at=$reg", which sets $at to $reg.
4813 MCAsmParser &Parser = getParser();
4814 Parser.Lex(); // Eat "at".
4816 if (getLexer().is(AsmToken::EndOfStatement)) {
4817 // No register was specified, so we set $at to $1.
4818 AssemblerOptions.back()->setATRegIndex(1);
4820 getTargetStreamer().emitDirectiveSetAt();
4821 Parser.Lex(); // Consume the EndOfStatement.
4825 if (getLexer().isNot(AsmToken::Equal)) {
4826 reportParseError("unexpected token, expected equals sign");
4829 Parser.Lex(); // Eat "=".
4831 if (getLexer().isNot(AsmToken::Dollar)) {
4832 if (getLexer().is(AsmToken::EndOfStatement)) {
4833 reportParseError("no register specified");
4836 reportParseError("unexpected token, expected dollar sign '$'");
4840 Parser.Lex(); // Eat "$".
4842 // Find out what "reg" is.
4844 const AsmToken &Reg = Parser.getTok();
4845 if (Reg.is(AsmToken::Identifier)) {
4846 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4847 } else if (Reg.is(AsmToken::Integer)) {
4848 AtRegNo = Reg.getIntVal();
4850 reportParseError("unexpected token, expected identifier or integer");
4854 // Check if $reg is a valid register. If it is, set $at to $reg.
4855 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4856 reportParseError("invalid register");
4859 Parser.Lex(); // Eat "reg".
4861 // If this is not the end of the statement, report an error.
4862 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4863 reportParseError("unexpected token, expected end of statement");
4867 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4869 Parser.Lex(); // Consume the EndOfStatement.
4873 bool MipsAsmParser::parseSetReorderDirective() {
4874 MCAsmParser &Parser = getParser();
4876 // If this is not the end of the statement, report an error.
4877 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4878 reportParseError("unexpected token, expected end of statement");
4881 AssemblerOptions.back()->setReorder();
4882 getTargetStreamer().emitDirectiveSetReorder();
4883 Parser.Lex(); // Consume the EndOfStatement.
4887 bool MipsAsmParser::parseSetNoReorderDirective() {
4888 MCAsmParser &Parser = getParser();
4890 // If this is not the end of the statement, report an error.
4891 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4892 reportParseError("unexpected token, expected end of statement");
4895 AssemblerOptions.back()->setNoReorder();
4896 getTargetStreamer().emitDirectiveSetNoReorder();
4897 Parser.Lex(); // Consume the EndOfStatement.
4901 bool MipsAsmParser::parseSetMacroDirective() {
4902 MCAsmParser &Parser = getParser();
4904 // If this is not the end of the statement, report an error.
4905 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4906 reportParseError("unexpected token, expected end of statement");
4909 AssemblerOptions.back()->setMacro();
4910 getTargetStreamer().emitDirectiveSetMacro();
4911 Parser.Lex(); // Consume the EndOfStatement.
4915 bool MipsAsmParser::parseSetNoMacroDirective() {
4916 MCAsmParser &Parser = getParser();
4918 // If this is not the end of the statement, report an error.
4919 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4920 reportParseError("unexpected token, expected end of statement");
4923 if (AssemblerOptions.back()->isReorder()) {
4924 reportParseError("`noreorder' must be set before `nomacro'");
4927 AssemblerOptions.back()->setNoMacro();
4928 getTargetStreamer().emitDirectiveSetNoMacro();
4929 Parser.Lex(); // Consume the EndOfStatement.
4933 bool MipsAsmParser::parseSetMsaDirective() {
4934 MCAsmParser &Parser = getParser();
4937 // If this is not the end of the statement, report an error.
4938 if (getLexer().isNot(AsmToken::EndOfStatement))
4939 return reportParseError("unexpected token, expected end of statement");
4941 setFeatureBits(Mips::FeatureMSA, "msa");
4942 getTargetStreamer().emitDirectiveSetMsa();
4946 bool MipsAsmParser::parseSetNoMsaDirective() {
4947 MCAsmParser &Parser = getParser();
4950 // If this is not the end of the statement, report an error.
4951 if (getLexer().isNot(AsmToken::EndOfStatement))
4952 return reportParseError("unexpected token, expected end of statement");
4954 clearFeatureBits(Mips::FeatureMSA, "msa");
4955 getTargetStreamer().emitDirectiveSetNoMsa();
4959 bool MipsAsmParser::parseSetNoDspDirective() {
4960 MCAsmParser &Parser = getParser();
4961 Parser.Lex(); // Eat "nodsp".
4963 // If this is not the end of the statement, report an error.
4964 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4965 reportParseError("unexpected token, expected end of statement");
4969 clearFeatureBits(Mips::FeatureDSP, "dsp");
4970 getTargetStreamer().emitDirectiveSetNoDsp();
4974 bool MipsAsmParser::parseSetMips16Directive() {
4975 MCAsmParser &Parser = getParser();
4976 Parser.Lex(); // Eat "mips16".
4978 // If this is not the end of the statement, report an error.
4979 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4980 reportParseError("unexpected token, expected end of statement");
4984 setFeatureBits(Mips::FeatureMips16, "mips16");
4985 getTargetStreamer().emitDirectiveSetMips16();
4986 Parser.Lex(); // Consume the EndOfStatement.
4990 bool MipsAsmParser::parseSetNoMips16Directive() {
4991 MCAsmParser &Parser = getParser();
4992 Parser.Lex(); // Eat "nomips16".
4994 // If this is not the end of the statement, report an error.
4995 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4996 reportParseError("unexpected token, expected end of statement");
5000 clearFeatureBits(Mips::FeatureMips16, "mips16");
5001 getTargetStreamer().emitDirectiveSetNoMips16();
5002 Parser.Lex(); // Consume the EndOfStatement.
5006 bool MipsAsmParser::parseSetFpDirective() {
5007 MCAsmParser &Parser = getParser();
5008 MipsABIFlagsSection::FpABIKind FpAbiVal;
5009 // Line can be: .set fp=32
5012 Parser.Lex(); // Eat fp token
5013 AsmToken Tok = Parser.getTok();
5014 if (Tok.isNot(AsmToken::Equal)) {
5015 reportParseError("unexpected token, expected equals sign '='");
5018 Parser.Lex(); // Eat '=' token.
5019 Tok = Parser.getTok();
5021 if (!parseFpABIValue(FpAbiVal, ".set"))
5024 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5025 reportParseError("unexpected token, expected end of statement");
5028 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5029 Parser.Lex(); // Consume the EndOfStatement.
5033 bool MipsAsmParser::parseSetOddSPRegDirective() {
5034 MCAsmParser &Parser = getParser();
5036 Parser.Lex(); // Eat "oddspreg".
5037 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5038 reportParseError("unexpected token, expected end of statement");
5042 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5043 getTargetStreamer().emitDirectiveSetOddSPReg();
5047 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5048 MCAsmParser &Parser = getParser();
5050 Parser.Lex(); // Eat "nooddspreg".
5051 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5052 reportParseError("unexpected token, expected end of statement");
5056 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5057 getTargetStreamer().emitDirectiveSetNoOddSPReg();
5061 bool MipsAsmParser::parseSetPopDirective() {
5062 MCAsmParser &Parser = getParser();
5063 SMLoc Loc = getLexer().getLoc();
5066 if (getLexer().isNot(AsmToken::EndOfStatement))
5067 return reportParseError("unexpected token, expected end of statement");
5069 // Always keep an element on the options "stack" to prevent the user
5070 // from changing the initial options. This is how we remember them.
5071 if (AssemblerOptions.size() == 2)
5072 return reportParseError(Loc, ".set pop with no .set push");
5074 MCSubtargetInfo &STI = copySTI();
5075 AssemblerOptions.pop_back();
5076 setAvailableFeatures(
5077 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5078 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
5080 getTargetStreamer().emitDirectiveSetPop();
5084 bool MipsAsmParser::parseSetPushDirective() {
5085 MCAsmParser &Parser = getParser();
5087 if (getLexer().isNot(AsmToken::EndOfStatement))
5088 return reportParseError("unexpected token, expected end of statement");
5090 // Create a copy of the current assembler options environment and push it.
5091 AssemblerOptions.push_back(
5092 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5094 getTargetStreamer().emitDirectiveSetPush();
5098 bool MipsAsmParser::parseSetSoftFloatDirective() {
5099 MCAsmParser &Parser = getParser();
5101 if (getLexer().isNot(AsmToken::EndOfStatement))
5102 return reportParseError("unexpected token, expected end of statement");
5104 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5105 getTargetStreamer().emitDirectiveSetSoftFloat();
5109 bool MipsAsmParser::parseSetHardFloatDirective() {
5110 MCAsmParser &Parser = getParser();
5112 if (getLexer().isNot(AsmToken::EndOfStatement))
5113 return reportParseError("unexpected token, expected end of statement");
5115 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5116 getTargetStreamer().emitDirectiveSetHardFloat();
5120 bool MipsAsmParser::parseSetAssignment() {
5122 const MCExpr *Value;
5123 MCAsmParser &Parser = getParser();
5125 if (Parser.parseIdentifier(Name))
5126 reportParseError("expected identifier after .set");
5128 if (getLexer().isNot(AsmToken::Comma))
5129 return reportParseError("unexpected token, expected comma");
5132 if (Parser.parseExpression(Value))
5133 return reportParseError("expected valid expression after comma");
5135 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5136 Sym->setVariableValue(Value);
5141 bool MipsAsmParser::parseSetMips0Directive() {
5142 MCAsmParser &Parser = getParser();
5144 if (getLexer().isNot(AsmToken::EndOfStatement))
5145 return reportParseError("unexpected token, expected end of statement");
5147 // Reset assembler options to their initial values.
5148 MCSubtargetInfo &STI = copySTI();
5149 setAvailableFeatures(
5150 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
5151 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
5152 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
5154 getTargetStreamer().emitDirectiveSetMips0();
5158 bool MipsAsmParser::parseSetArchDirective() {
5159 MCAsmParser &Parser = getParser();
5161 if (getLexer().isNot(AsmToken::Equal))
5162 return reportParseError("unexpected token, expected equals sign");
5166 if (Parser.parseIdentifier(Arch))
5167 return reportParseError("expected arch identifier");
5169 StringRef ArchFeatureName =
5170 StringSwitch<StringRef>(Arch)
5171 .Case("mips1", "mips1")
5172 .Case("mips2", "mips2")
5173 .Case("mips3", "mips3")
5174 .Case("mips4", "mips4")
5175 .Case("mips5", "mips5")
5176 .Case("mips32", "mips32")
5177 .Case("mips32r2", "mips32r2")
5178 .Case("mips32r3", "mips32r3")
5179 .Case("mips32r5", "mips32r5")
5180 .Case("mips32r6", "mips32r6")
5181 .Case("mips64", "mips64")
5182 .Case("mips64r2", "mips64r2")
5183 .Case("mips64r3", "mips64r3")
5184 .Case("mips64r5", "mips64r5")
5185 .Case("mips64r6", "mips64r6")
5186 .Case("cnmips", "cnmips")
5187 .Case("r4000", "mips3") // This is an implementation of Mips3.
5190 if (ArchFeatureName.empty())
5191 return reportParseError("unsupported architecture");
5193 selectArch(ArchFeatureName);
5194 getTargetStreamer().emitDirectiveSetArch(Arch);
5198 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
5199 MCAsmParser &Parser = getParser();
5201 if (getLexer().isNot(AsmToken::EndOfStatement))
5202 return reportParseError("unexpected token, expected end of statement");
5206 llvm_unreachable("Unimplemented feature");
5207 case Mips::FeatureDSP:
5208 setFeatureBits(Mips::FeatureDSP, "dsp");
5209 getTargetStreamer().emitDirectiveSetDsp();
5211 case Mips::FeatureMicroMips:
5212 getTargetStreamer().emitDirectiveSetMicroMips();
5214 case Mips::FeatureMips1:
5215 selectArch("mips1");
5216 getTargetStreamer().emitDirectiveSetMips1();
5218 case Mips::FeatureMips2:
5219 selectArch("mips2");
5220 getTargetStreamer().emitDirectiveSetMips2();
5222 case Mips::FeatureMips3:
5223 selectArch("mips3");
5224 getTargetStreamer().emitDirectiveSetMips3();
5226 case Mips::FeatureMips4:
5227 selectArch("mips4");
5228 getTargetStreamer().emitDirectiveSetMips4();
5230 case Mips::FeatureMips5:
5231 selectArch("mips5");
5232 getTargetStreamer().emitDirectiveSetMips5();
5234 case Mips::FeatureMips32:
5235 selectArch("mips32");
5236 getTargetStreamer().emitDirectiveSetMips32();
5238 case Mips::FeatureMips32r2:
5239 selectArch("mips32r2");
5240 getTargetStreamer().emitDirectiveSetMips32R2();
5242 case Mips::FeatureMips32r3:
5243 selectArch("mips32r3");
5244 getTargetStreamer().emitDirectiveSetMips32R3();
5246 case Mips::FeatureMips32r5:
5247 selectArch("mips32r5");
5248 getTargetStreamer().emitDirectiveSetMips32R5();
5250 case Mips::FeatureMips32r6:
5251 selectArch("mips32r6");
5252 getTargetStreamer().emitDirectiveSetMips32R6();
5254 case Mips::FeatureMips64:
5255 selectArch("mips64");
5256 getTargetStreamer().emitDirectiveSetMips64();
5258 case Mips::FeatureMips64r2:
5259 selectArch("mips64r2");
5260 getTargetStreamer().emitDirectiveSetMips64R2();
5262 case Mips::FeatureMips64r3:
5263 selectArch("mips64r3");
5264 getTargetStreamer().emitDirectiveSetMips64R3();
5266 case Mips::FeatureMips64r5:
5267 selectArch("mips64r5");
5268 getTargetStreamer().emitDirectiveSetMips64R5();
5270 case Mips::FeatureMips64r6:
5271 selectArch("mips64r6");
5272 getTargetStreamer().emitDirectiveSetMips64R6();
5278 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
5279 MCAsmParser &Parser = getParser();
5280 if (getLexer().isNot(AsmToken::Comma)) {
5281 SMLoc Loc = getLexer().getLoc();
5282 Parser.eatToEndOfStatement();
5283 return Error(Loc, ErrorStr);
5286 Parser.Lex(); // Eat the comma.
5290 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
5291 // In this class, it is only used for .cprestore.
5292 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
5293 // MipsTargetELFStreamer and MipsAsmParser.
5294 bool MipsAsmParser::isPicAndNotNxxAbi() {
5295 return inPicMode() && !(isABI_N32() || isABI_N64());
5298 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
5299 if (AssemblerOptions.back()->isReorder())
5300 Warning(Loc, ".cpload should be inside a noreorder section");
5302 if (inMips16Mode()) {
5303 reportParseError(".cpload is not supported in Mips16 mode");
5307 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
5308 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
5309 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5310 reportParseError("expected register containing function address");
5314 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
5315 if (!RegOpnd.isGPRAsmReg()) {
5316 reportParseError(RegOpnd.getStartLoc(), "invalid register");
5320 // If this is not the end of the statement, report an error.
5321 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5322 reportParseError("unexpected token, expected end of statement");
5326 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5330 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5331 MCAsmParser &Parser = getParser();
5333 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5334 // is used in non-PIC mode.
5336 if (inMips16Mode()) {
5337 reportParseError(".cprestore is not supported in Mips16 mode");
5341 // Get the stack offset value.
5342 const MCExpr *StackOffset;
5343 int64_t StackOffsetVal;
5344 if (Parser.parseExpression(StackOffset)) {
5345 reportParseError("expected stack offset value");
5349 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5350 reportParseError("stack offset is not an absolute expression");
5354 if (StackOffsetVal < 0) {
5355 Warning(Loc, ".cprestore with negative stack offset has no effect");
5356 IsCpRestoreSet = false;
5358 IsCpRestoreSet = true;
5359 CpRestoreOffset = StackOffsetVal;
5362 // If this is not the end of the statement, report an error.
5363 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5364 reportParseError("unexpected token, expected end of statement");
5368 // Store the $gp on the stack.
5369 SmallVector<MCInst, 3> StoreInsts;
5370 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5373 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
5374 Parser.Lex(); // Consume the EndOfStatement.
5378 bool MipsAsmParser::parseDirectiveCPSetup() {
5379 MCAsmParser &Parser = getParser();
5382 bool SaveIsReg = true;
5384 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5385 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5386 if (ResTy == MatchOperand_NoMatch) {
5387 reportParseError("expected register containing function address");
5388 Parser.eatToEndOfStatement();
5392 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5393 if (!FuncRegOpnd.isGPRAsmReg()) {
5394 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5395 Parser.eatToEndOfStatement();
5399 FuncReg = FuncRegOpnd.getGPR32Reg();
5402 if (!eatComma("unexpected token, expected comma"))
5405 ResTy = parseAnyRegister(TmpReg);
5406 if (ResTy == MatchOperand_NoMatch) {
5407 const MCExpr *OffsetExpr;
5409 SMLoc ExprLoc = getLexer().getLoc();
5411 if (Parser.parseExpression(OffsetExpr) ||
5412 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5413 reportParseError(ExprLoc, "expected save register or stack offset");
5414 Parser.eatToEndOfStatement();
5421 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5422 if (!SaveOpnd.isGPRAsmReg()) {
5423 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5424 Parser.eatToEndOfStatement();
5427 Save = SaveOpnd.getGPR32Reg();
5430 if (!eatComma("unexpected token, expected comma"))
5434 if (Parser.parseExpression(Expr)) {
5435 reportParseError("expected expression");
5439 if (Expr->getKind() != MCExpr::SymbolRef) {
5440 reportParseError("expected symbol");
5443 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5445 CpSaveLocation = Save;
5446 CpSaveLocationIsRegister = SaveIsReg;
5448 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5453 bool MipsAsmParser::parseDirectiveCPReturn() {
5454 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5455 CpSaveLocationIsRegister);
5459 bool MipsAsmParser::parseDirectiveNaN() {
5460 MCAsmParser &Parser = getParser();
5461 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5462 const AsmToken &Tok = Parser.getTok();
5464 if (Tok.getString() == "2008") {
5466 getTargetStreamer().emitDirectiveNaN2008();
5468 } else if (Tok.getString() == "legacy") {
5470 getTargetStreamer().emitDirectiveNaNLegacy();
5474 // If we don't recognize the option passed to the .nan
5475 // directive (e.g. no option or unknown option), emit an error.
5476 reportParseError("invalid option in .nan directive");
5480 bool MipsAsmParser::parseDirectiveSet() {
5481 MCAsmParser &Parser = getParser();
5482 // Get the next token.
5483 const AsmToken &Tok = Parser.getTok();
5485 if (Tok.getString() == "noat") {
5486 return parseSetNoAtDirective();
5487 } else if (Tok.getString() == "at") {
5488 return parseSetAtDirective();
5489 } else if (Tok.getString() == "arch") {
5490 return parseSetArchDirective();
5491 } else if (Tok.getString() == "fp") {
5492 return parseSetFpDirective();
5493 } else if (Tok.getString() == "oddspreg") {
5494 return parseSetOddSPRegDirective();
5495 } else if (Tok.getString() == "nooddspreg") {
5496 return parseSetNoOddSPRegDirective();
5497 } else if (Tok.getString() == "pop") {
5498 return parseSetPopDirective();
5499 } else if (Tok.getString() == "push") {
5500 return parseSetPushDirective();
5501 } else if (Tok.getString() == "reorder") {
5502 return parseSetReorderDirective();
5503 } else if (Tok.getString() == "noreorder") {
5504 return parseSetNoReorderDirective();
5505 } else if (Tok.getString() == "macro") {
5506 return parseSetMacroDirective();
5507 } else if (Tok.getString() == "nomacro") {
5508 return parseSetNoMacroDirective();
5509 } else if (Tok.getString() == "mips16") {
5510 return parseSetMips16Directive();
5511 } else if (Tok.getString() == "nomips16") {
5512 return parseSetNoMips16Directive();
5513 } else if (Tok.getString() == "nomicromips") {
5514 getTargetStreamer().emitDirectiveSetNoMicroMips();
5515 Parser.eatToEndOfStatement();
5517 } else if (Tok.getString() == "micromips") {
5518 return parseSetFeature(Mips::FeatureMicroMips);
5519 } else if (Tok.getString() == "mips0") {
5520 return parseSetMips0Directive();
5521 } else if (Tok.getString() == "mips1") {
5522 return parseSetFeature(Mips::FeatureMips1);
5523 } else if (Tok.getString() == "mips2") {
5524 return parseSetFeature(Mips::FeatureMips2);
5525 } else if (Tok.getString() == "mips3") {
5526 return parseSetFeature(Mips::FeatureMips3);
5527 } else if (Tok.getString() == "mips4") {
5528 return parseSetFeature(Mips::FeatureMips4);
5529 } else if (Tok.getString() == "mips5") {
5530 return parseSetFeature(Mips::FeatureMips5);
5531 } else if (Tok.getString() == "mips32") {
5532 return parseSetFeature(Mips::FeatureMips32);
5533 } else if (Tok.getString() == "mips32r2") {
5534 return parseSetFeature(Mips::FeatureMips32r2);
5535 } else if (Tok.getString() == "mips32r3") {
5536 return parseSetFeature(Mips::FeatureMips32r3);
5537 } else if (Tok.getString() == "mips32r5") {
5538 return parseSetFeature(Mips::FeatureMips32r5);
5539 } else if (Tok.getString() == "mips32r6") {
5540 return parseSetFeature(Mips::FeatureMips32r6);
5541 } else if (Tok.getString() == "mips64") {
5542 return parseSetFeature(Mips::FeatureMips64);
5543 } else if (Tok.getString() == "mips64r2") {
5544 return parseSetFeature(Mips::FeatureMips64r2);
5545 } else if (Tok.getString() == "mips64r3") {
5546 return parseSetFeature(Mips::FeatureMips64r3);
5547 } else if (Tok.getString() == "mips64r5") {
5548 return parseSetFeature(Mips::FeatureMips64r5);
5549 } else if (Tok.getString() == "mips64r6") {
5550 return parseSetFeature(Mips::FeatureMips64r6);
5551 } else if (Tok.getString() == "dsp") {
5552 return parseSetFeature(Mips::FeatureDSP);
5553 } else if (Tok.getString() == "nodsp") {
5554 return parseSetNoDspDirective();
5555 } else if (Tok.getString() == "msa") {
5556 return parseSetMsaDirective();
5557 } else if (Tok.getString() == "nomsa") {
5558 return parseSetNoMsaDirective();
5559 } else if (Tok.getString() == "softfloat") {
5560 return parseSetSoftFloatDirective();
5561 } else if (Tok.getString() == "hardfloat") {
5562 return parseSetHardFloatDirective();
5564 // It is just an identifier, look for an assignment.
5565 parseSetAssignment();
5572 /// parseDataDirective
5573 /// ::= .word [ expression (, expression)* ]
5574 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5575 MCAsmParser &Parser = getParser();
5576 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5578 const MCExpr *Value;
5579 if (getParser().parseExpression(Value))
5582 getParser().getStreamer().EmitValue(Value, Size);
5584 if (getLexer().is(AsmToken::EndOfStatement))
5587 if (getLexer().isNot(AsmToken::Comma))
5588 return Error(L, "unexpected token, expected comma");
5597 /// parseDirectiveGpWord
5598 /// ::= .gpword local_sym
5599 bool MipsAsmParser::parseDirectiveGpWord() {
5600 MCAsmParser &Parser = getParser();
5601 const MCExpr *Value;
5602 // EmitGPRel32Value requires an expression, so we are using base class
5603 // method to evaluate the expression.
5604 if (getParser().parseExpression(Value))
5606 getParser().getStreamer().EmitGPRel32Value(Value);
5608 if (getLexer().isNot(AsmToken::EndOfStatement))
5609 return Error(getLexer().getLoc(),
5610 "unexpected token, expected end of statement");
5611 Parser.Lex(); // Eat EndOfStatement token.
5615 /// parseDirectiveGpDWord
5616 /// ::= .gpdword local_sym
5617 bool MipsAsmParser::parseDirectiveGpDWord() {
5618 MCAsmParser &Parser = getParser();
5619 const MCExpr *Value;
5620 // EmitGPRel64Value requires an expression, so we are using base class
5621 // method to evaluate the expression.
5622 if (getParser().parseExpression(Value))
5624 getParser().getStreamer().EmitGPRel64Value(Value);
5626 if (getLexer().isNot(AsmToken::EndOfStatement))
5627 return Error(getLexer().getLoc(),
5628 "unexpected token, expected end of statement");
5629 Parser.Lex(); // Eat EndOfStatement token.
5633 bool MipsAsmParser::parseDirectiveOption() {
5634 MCAsmParser &Parser = getParser();
5635 // Get the option token.
5636 AsmToken Tok = Parser.getTok();
5637 // At the moment only identifiers are supported.
5638 if (Tok.isNot(AsmToken::Identifier)) {
5639 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5640 Parser.eatToEndOfStatement();
5644 StringRef Option = Tok.getIdentifier();
5646 if (Option == "pic0") {
5647 // MipsAsmParser needs to know if the current PIC mode changes.
5648 IsPicEnabled = false;
5650 getTargetStreamer().emitDirectiveOptionPic0();
5652 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5653 Error(Parser.getTok().getLoc(),
5654 "unexpected token, expected end of statement");
5655 Parser.eatToEndOfStatement();
5660 if (Option == "pic2") {
5661 // MipsAsmParser needs to know if the current PIC mode changes.
5662 IsPicEnabled = true;
5664 getTargetStreamer().emitDirectiveOptionPic2();
5666 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5667 Error(Parser.getTok().getLoc(),
5668 "unexpected token, expected end of statement");
5669 Parser.eatToEndOfStatement();
5675 Warning(Parser.getTok().getLoc(),
5676 "unknown option, expected 'pic0' or 'pic2'");
5677 Parser.eatToEndOfStatement();
5681 /// parseInsnDirective
5683 bool MipsAsmParser::parseInsnDirective() {
5684 // If this is not the end of the statement, report an error.
5685 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5686 reportParseError("unexpected token, expected end of statement");
5690 // The actual label marking happens in
5691 // MipsELFStreamer::createPendingLabelRelocs().
5692 getTargetStreamer().emitDirectiveInsn();
5694 getParser().Lex(); // Eat EndOfStatement token.
5698 /// parseDirectiveModule
5699 /// ::= .module oddspreg
5700 /// ::= .module nooddspreg
5701 /// ::= .module fp=value
5702 /// ::= .module softfloat
5703 /// ::= .module hardfloat
5704 bool MipsAsmParser::parseDirectiveModule() {
5705 MCAsmParser &Parser = getParser();
5706 MCAsmLexer &Lexer = getLexer();
5707 SMLoc L = Lexer.getLoc();
5709 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5710 // TODO : get a better message.
5711 reportParseError(".module directive must appear before any code");
5716 if (Parser.parseIdentifier(Option)) {
5717 reportParseError("expected .module option identifier");
5721 if (Option == "oddspreg") {
5722 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5724 // Synchronize the abiflags information with the FeatureBits information we
5726 getTargetStreamer().updateABIInfo(*this);
5728 // If printing assembly, use the recently updated abiflags information.
5729 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5730 // emitted at the end).
5731 getTargetStreamer().emitDirectiveModuleOddSPReg();
5733 // If this is not the end of the statement, report an error.
5734 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5735 reportParseError("unexpected token, expected end of statement");
5739 return false; // parseDirectiveModule has finished successfully.
5740 } else if (Option == "nooddspreg") {
5742 Error(L, "'.module nooddspreg' requires the O32 ABI");
5746 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5748 // Synchronize the abiflags information with the FeatureBits information we
5750 getTargetStreamer().updateABIInfo(*this);
5752 // If printing assembly, use the recently updated abiflags information.
5753 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5754 // emitted at the end).
5755 getTargetStreamer().emitDirectiveModuleOddSPReg();
5757 // If this is not the end of the statement, report an error.
5758 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5759 reportParseError("unexpected token, expected end of statement");
5763 return false; // parseDirectiveModule has finished successfully.
5764 } else if (Option == "fp") {
5765 return parseDirectiveModuleFP();
5766 } else if (Option == "softfloat") {
5767 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5769 // Synchronize the ABI Flags information with the FeatureBits information we
5771 getTargetStreamer().updateABIInfo(*this);
5773 // If printing assembly, use the recently updated ABI Flags information.
5774 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5776 getTargetStreamer().emitDirectiveModuleSoftFloat();
5778 // If this is not the end of the statement, report an error.
5779 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5780 reportParseError("unexpected token, expected end of statement");
5784 return false; // parseDirectiveModule has finished successfully.
5785 } else if (Option == "hardfloat") {
5786 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5788 // Synchronize the ABI Flags information with the FeatureBits information we
5790 getTargetStreamer().updateABIInfo(*this);
5792 // If printing assembly, use the recently updated ABI Flags information.
5793 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5795 getTargetStreamer().emitDirectiveModuleHardFloat();
5797 // If this is not the end of the statement, report an error.
5798 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5799 reportParseError("unexpected token, expected end of statement");
5803 return false; // parseDirectiveModule has finished successfully.
5805 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5809 /// parseDirectiveModuleFP
5813 bool MipsAsmParser::parseDirectiveModuleFP() {
5814 MCAsmParser &Parser = getParser();
5815 MCAsmLexer &Lexer = getLexer();
5817 if (Lexer.isNot(AsmToken::Equal)) {
5818 reportParseError("unexpected token, expected equals sign '='");
5821 Parser.Lex(); // Eat '=' token.
5823 MipsABIFlagsSection::FpABIKind FpABI;
5824 if (!parseFpABIValue(FpABI, ".module"))
5827 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5828 reportParseError("unexpected token, expected end of statement");
5832 // Synchronize the abiflags information with the FeatureBits information we
5834 getTargetStreamer().updateABIInfo(*this);
5836 // If printing assembly, use the recently updated abiflags information.
5837 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5838 // emitted at the end).
5839 getTargetStreamer().emitDirectiveModuleFP();
5841 Parser.Lex(); // Consume the EndOfStatement.
5845 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5846 StringRef Directive) {
5847 MCAsmParser &Parser = getParser();
5848 MCAsmLexer &Lexer = getLexer();
5849 bool ModuleLevelOptions = Directive == ".module";
5851 if (Lexer.is(AsmToken::Identifier)) {
5852 StringRef Value = Parser.getTok().getString();
5855 if (Value != "xx") {
5856 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5861 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5865 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5866 if (ModuleLevelOptions) {
5867 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5868 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5870 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5871 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5876 if (Lexer.is(AsmToken::Integer)) {
5877 unsigned Value = Parser.getTok().getIntVal();
5880 if (Value != 32 && Value != 64) {
5881 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5887 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5891 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5892 if (ModuleLevelOptions) {
5893 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5894 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5896 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5897 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5900 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5901 if (ModuleLevelOptions) {
5902 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5903 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5905 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5906 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5916 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5917 MCAsmParser &Parser = getParser();
5918 StringRef IDVal = DirectiveID.getString();
5920 if (IDVal == ".cpload")
5921 return parseDirectiveCpLoad(DirectiveID.getLoc());
5922 if (IDVal == ".cprestore")
5923 return parseDirectiveCpRestore(DirectiveID.getLoc());
5924 if (IDVal == ".dword") {
5925 parseDataDirective(8, DirectiveID.getLoc());
5928 if (IDVal == ".ent") {
5929 StringRef SymbolName;
5931 if (Parser.parseIdentifier(SymbolName)) {
5932 reportParseError("expected identifier after .ent");
5936 // There's an undocumented extension that allows an integer to
5937 // follow the name of the procedure which AFAICS is ignored by GAS.
5938 // Example: .ent foo,2
5939 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5940 if (getLexer().isNot(AsmToken::Comma)) {
5941 // Even though we accept this undocumented extension for compatibility
5942 // reasons, the additional integer argument does not actually change
5943 // the behaviour of the '.ent' directive, so we would like to discourage
5944 // its use. We do this by not referring to the extended version in
5945 // error messages which are not directly related to its use.
5946 reportParseError("unexpected token, expected end of statement");
5949 Parser.Lex(); // Eat the comma.
5950 const MCExpr *DummyNumber;
5951 int64_t DummyNumberVal;
5952 // If the user was explicitly trying to use the extended version,
5953 // we still give helpful extension-related error messages.
5954 if (Parser.parseExpression(DummyNumber)) {
5955 reportParseError("expected number after comma");
5958 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5959 reportParseError("expected an absolute expression after comma");
5964 // If this is not the end of the statement, report an error.
5965 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5966 reportParseError("unexpected token, expected end of statement");
5970 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5972 getTargetStreamer().emitDirectiveEnt(*Sym);
5974 IsCpRestoreSet = false;
5978 if (IDVal == ".end") {
5979 StringRef SymbolName;
5981 if (Parser.parseIdentifier(SymbolName)) {
5982 reportParseError("expected identifier after .end");
5986 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5987 reportParseError("unexpected token, expected end of statement");
5991 if (CurrentFn == nullptr) {
5992 reportParseError(".end used without .ent");
5996 if ((SymbolName != CurrentFn->getName())) {
5997 reportParseError(".end symbol does not match .ent symbol");
6001 getTargetStreamer().emitDirectiveEnd(SymbolName);
6002 CurrentFn = nullptr;
6003 IsCpRestoreSet = false;
6007 if (IDVal == ".frame") {
6008 // .frame $stack_reg, frame_size_in_bytes, $return_reg
6009 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6010 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6011 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6012 reportParseError("expected stack register");
6016 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6017 if (!StackRegOpnd.isGPRAsmReg()) {
6018 reportParseError(StackRegOpnd.getStartLoc(),
6019 "expected general purpose register");
6022 unsigned StackReg = StackRegOpnd.getGPR32Reg();
6024 if (Parser.getTok().is(AsmToken::Comma))
6027 reportParseError("unexpected token, expected comma");
6031 // Parse the frame size.
6032 const MCExpr *FrameSize;
6033 int64_t FrameSizeVal;
6035 if (Parser.parseExpression(FrameSize)) {
6036 reportParseError("expected frame size value");
6040 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
6041 reportParseError("frame size not an absolute expression");
6045 if (Parser.getTok().is(AsmToken::Comma))
6048 reportParseError("unexpected token, expected comma");
6052 // Parse the return register.
6054 ResTy = parseAnyRegister(TmpReg);
6055 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6056 reportParseError("expected return register");
6060 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6061 if (!ReturnRegOpnd.isGPRAsmReg()) {
6062 reportParseError(ReturnRegOpnd.getStartLoc(),
6063 "expected general purpose register");
6067 // If this is not the end of the statement, report an error.
6068 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6069 reportParseError("unexpected token, expected end of statement");
6073 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
6074 ReturnRegOpnd.getGPR32Reg());
6075 IsCpRestoreSet = false;
6079 if (IDVal == ".set") {
6080 return parseDirectiveSet();
6083 if (IDVal == ".mask" || IDVal == ".fmask") {
6084 // .mask bitmask, frame_offset
6085 // bitmask: One bit for each register used.
6086 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
6087 // first register is expected to be saved.
6089 // .mask 0x80000000, -4
6090 // .fmask 0x80000000, -4
6093 // Parse the bitmask
6094 const MCExpr *BitMask;
6097 if (Parser.parseExpression(BitMask)) {
6098 reportParseError("expected bitmask value");
6102 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
6103 reportParseError("bitmask not an absolute expression");
6107 if (Parser.getTok().is(AsmToken::Comma))
6110 reportParseError("unexpected token, expected comma");
6114 // Parse the frame_offset
6115 const MCExpr *FrameOffset;
6116 int64_t FrameOffsetVal;
6118 if (Parser.parseExpression(FrameOffset)) {
6119 reportParseError("expected frame offset value");
6123 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
6124 reportParseError("frame offset not an absolute expression");
6128 // If this is not the end of the statement, report an error.
6129 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6130 reportParseError("unexpected token, expected end of statement");
6134 if (IDVal == ".mask")
6135 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
6137 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6141 if (IDVal == ".nan")
6142 return parseDirectiveNaN();
6144 if (IDVal == ".gpword") {
6145 parseDirectiveGpWord();
6149 if (IDVal == ".gpdword") {
6150 parseDirectiveGpDWord();
6154 if (IDVal == ".word") {
6155 parseDataDirective(4, DirectiveID.getLoc());
6159 if (IDVal == ".option")
6160 return parseDirectiveOption();
6162 if (IDVal == ".abicalls") {
6163 getTargetStreamer().emitDirectiveAbiCalls();
6164 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6165 Error(Parser.getTok().getLoc(),
6166 "unexpected token, expected end of statement");
6168 Parser.eatToEndOfStatement();
6173 if (IDVal == ".cpsetup")
6174 return parseDirectiveCPSetup();
6176 if (IDVal == ".cpreturn")
6177 return parseDirectiveCPReturn();
6179 if (IDVal == ".module")
6180 return parseDirectiveModule();
6182 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
6183 return parseInternalDirectiveReallowModule();
6185 if (IDVal == ".insn")
6186 return parseInsnDirective();
6191 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
6192 // If this is not the end of the statement, report an error.
6193 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6194 reportParseError("unexpected token, expected end of statement");
6198 getTargetStreamer().reallowModuleDirective();
6200 getParser().Lex(); // Eat EndOfStatement token.
6204 extern "C" void LLVMInitializeMipsAsmParser() {
6205 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
6206 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
6207 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
6208 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
6211 #define GET_REGISTER_MATCHER
6212 #define GET_MATCHER_IMPLEMENTATION
6213 #include "MipsGenAsmMatcher.inc"