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, int AdjustOffset = 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;
938 Inst.addOperand(MCOperand::createImm(Imm));
941 void addImmOperands(MCInst &Inst, unsigned N) const {
942 assert(N == 1 && "Invalid number of operands!");
943 const MCExpr *Expr = getImm();
947 void addMemOperands(MCInst &Inst, unsigned N) const {
948 assert(N == 2 && "Invalid number of operands!");
950 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
951 ? getMemBase()->getGPR64Reg()
952 : getMemBase()->getGPR32Reg()));
954 const MCExpr *Expr = getMemOff();
958 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
959 assert(N == 2 && "Invalid number of operands!");
961 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
963 const MCExpr *Expr = getMemOff();
967 void addRegListOperands(MCInst &Inst, unsigned N) const {
968 assert(N == 1 && "Invalid number of operands!");
970 for (auto RegNo : getRegList())
971 Inst.addOperand(MCOperand::createReg(RegNo));
974 void addRegPairOperands(MCInst &Inst, unsigned N) const {
975 assert(N == 2 && "Invalid number of operands!");
976 unsigned RegNo = getRegPair();
977 Inst.addOperand(MCOperand::createReg(RegNo++));
978 Inst.addOperand(MCOperand::createReg(RegNo));
981 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
982 assert(N == 2 && "Invalid number of operands!");
983 for (auto RegNo : getRegList())
984 Inst.addOperand(MCOperand::createReg(RegNo));
987 bool isReg() const override {
988 // As a special case until we sort out the definition of div/divu, pretend
989 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
990 if (isGPRAsmReg() && RegIdx.Index == 0)
993 return Kind == k_PhysRegister;
995 bool isRegIdx() const { return Kind == k_RegisterIndex; }
996 bool isImm() const override { return Kind == k_Immediate; }
997 bool isConstantImm() const {
998 return isImm() && isa<MCConstantExpr>(getImm());
1000 bool isConstantImmz() const {
1001 return isConstantImm() && getConstantImm() == 0;
1003 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1004 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1006 template <unsigned Bits> bool isConstantSImm() const {
1007 return isConstantImm() && isInt<Bits>(getConstantImm());
1009 bool isToken() const override {
1010 // Note: It's not possible to pretend that other operand kinds are tokens.
1011 // The matcher emitter checks tokens first.
1012 return Kind == k_Token;
1014 bool isMem() const override { return Kind == k_Memory; }
1015 bool isConstantMemOff() const {
1016 return isMem() && isa<MCConstantExpr>(getMemOff());
1018 template <unsigned Bits> bool isMemWithSimmOffset() const {
1019 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1020 && getMemBase()->isGPRAsmReg();
1022 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
1023 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
1024 getMemBase()->isGPRAsmReg();
1026 bool isMemWithGRPMM16Base() const {
1027 return isMem() && getMemBase()->isMM16AsmReg();
1029 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1030 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1031 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1033 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1034 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1035 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1036 && (getMemBase()->getGPR32Reg() == Mips::SP);
1038 template <unsigned Bits, unsigned ShiftLeftAmount>
1039 bool isScaledUImm() const {
1040 return isConstantImm() &&
1041 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1043 bool isRegList16() const {
1047 int Size = RegList.List->size();
1048 if (Size < 2 || Size > 5)
1051 unsigned R0 = RegList.List->front();
1052 unsigned R1 = RegList.List->back();
1053 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1054 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1057 int PrevReg = *RegList.List->begin();
1058 for (int i = 1; i < Size - 1; i++) {
1059 int Reg = (*(RegList.List))[i];
1060 if ( Reg != PrevReg + 1)
1067 bool isInvNum() const { return Kind == k_Immediate; }
1068 bool isLSAImm() const {
1069 if (!isConstantImm())
1071 int64_t Val = getConstantImm();
1072 return 1 <= Val && Val <= 4;
1074 bool isRegList() const { return Kind == k_RegList; }
1075 bool isMovePRegPair() const {
1076 if (Kind != k_RegList || RegList.List->size() != 2)
1079 unsigned R0 = RegList.List->front();
1080 unsigned R1 = RegList.List->back();
1082 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1083 (R0 == Mips::A1 && R1 == Mips::A3) ||
1084 (R0 == Mips::A2 && R1 == Mips::A3) ||
1085 (R0 == Mips::A0 && R1 == Mips::S5) ||
1086 (R0 == Mips::A0 && R1 == Mips::S6) ||
1087 (R0 == Mips::A0 && R1 == Mips::A1) ||
1088 (R0 == Mips::A0 && R1 == Mips::A2) ||
1089 (R0 == Mips::A0 && R1 == Mips::A3))
1095 StringRef getToken() const {
1096 assert(Kind == k_Token && "Invalid access!");
1097 return StringRef(Tok.Data, Tok.Length);
1099 bool isRegPair() const { return Kind == k_RegPair; }
1101 unsigned getReg() const override {
1102 // As a special case until we sort out the definition of div/divu, pretend
1103 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1104 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1105 RegIdx.Kind & RegKind_GPR)
1106 return getGPR32Reg(); // FIXME: GPR64 too
1108 assert(Kind == k_PhysRegister && "Invalid access!");
1112 const MCExpr *getImm() const {
1113 assert((Kind == k_Immediate) && "Invalid access!");
1117 int64_t getConstantImm() const {
1118 const MCExpr *Val = getImm();
1119 return static_cast<const MCConstantExpr *>(Val)->getValue();
1122 MipsOperand *getMemBase() const {
1123 assert((Kind == k_Memory) && "Invalid access!");
1127 const MCExpr *getMemOff() const {
1128 assert((Kind == k_Memory) && "Invalid access!");
1132 int64_t getConstantMemOff() const {
1133 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1136 const SmallVectorImpl<unsigned> &getRegList() const {
1137 assert((Kind == k_RegList) && "Invalid access!");
1138 return *(RegList.List);
1141 unsigned getRegPair() const {
1142 assert((Kind == k_RegPair) && "Invalid access!");
1143 return RegIdx.Index;
1146 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1147 MipsAsmParser &Parser) {
1148 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1149 Op->Tok.Data = Str.data();
1150 Op->Tok.Length = Str.size();
1156 /// Create a numeric register (e.g. $1). The exact register remains
1157 /// unresolved until an instruction successfully matches
1158 static std::unique_ptr<MipsOperand>
1159 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1160 SMLoc E, MipsAsmParser &Parser) {
1161 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1162 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1165 /// Create a register that is definitely a GPR.
1166 /// This is typically only used for named registers such as $gp.
1167 static std::unique_ptr<MipsOperand>
1168 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1169 MipsAsmParser &Parser) {
1170 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1173 /// Create a register that is definitely a FGR.
1174 /// This is typically only used for named registers such as $f0.
1175 static std::unique_ptr<MipsOperand>
1176 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1177 MipsAsmParser &Parser) {
1178 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1181 /// Create a register that is definitely a HWReg.
1182 /// This is typically only used for named registers such as $hwr_cpunum.
1183 static std::unique_ptr<MipsOperand>
1184 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1185 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1186 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1189 /// Create a register that is definitely an FCC.
1190 /// This is typically only used for named registers such as $fcc0.
1191 static std::unique_ptr<MipsOperand>
1192 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1193 MipsAsmParser &Parser) {
1194 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1197 /// Create a register that is definitely an ACC.
1198 /// This is typically only used for named registers such as $ac0.
1199 static std::unique_ptr<MipsOperand>
1200 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1201 MipsAsmParser &Parser) {
1202 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1205 /// Create a register that is definitely an MSA128.
1206 /// This is typically only used for named registers such as $w0.
1207 static std::unique_ptr<MipsOperand>
1208 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1209 SMLoc E, MipsAsmParser &Parser) {
1210 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1213 /// Create a register that is definitely an MSACtrl.
1214 /// This is typically only used for named registers such as $msaaccess.
1215 static std::unique_ptr<MipsOperand>
1216 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1217 SMLoc E, MipsAsmParser &Parser) {
1218 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1221 static std::unique_ptr<MipsOperand>
1222 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1223 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1230 static std::unique_ptr<MipsOperand>
1231 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1232 SMLoc E, MipsAsmParser &Parser) {
1233 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1234 Op->Mem.Base = Base.release();
1241 static std::unique_ptr<MipsOperand>
1242 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1243 MipsAsmParser &Parser) {
1244 assert (Regs.size() > 0 && "Empty list not allowed");
1246 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1247 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1248 Op->StartLoc = StartLoc;
1249 Op->EndLoc = EndLoc;
1253 static std::unique_ptr<MipsOperand>
1254 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1255 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1256 Op->RegIdx.Index = RegNo;
1262 bool isGPRAsmReg() const {
1263 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1265 bool isMM16AsmReg() const {
1266 if (!(isRegIdx() && RegIdx.Kind))
1268 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1269 || RegIdx.Index == 16 || RegIdx.Index == 17);
1271 bool isMM16AsmRegZero() const {
1272 if (!(isRegIdx() && RegIdx.Kind))
1274 return (RegIdx.Index == 0 ||
1275 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1276 RegIdx.Index == 17);
1278 bool isMM16AsmRegMoveP() const {
1279 if (!(isRegIdx() && RegIdx.Kind))
1281 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1282 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1284 bool isFGRAsmReg() const {
1285 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1286 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1288 bool isHWRegsAsmReg() const {
1289 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1291 bool isCCRAsmReg() const {
1292 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1294 bool isFCCAsmReg() const {
1295 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1297 if (!AsmParser.hasEightFccRegisters())
1298 return RegIdx.Index == 0;
1299 return RegIdx.Index <= 7;
1301 bool isACCAsmReg() const {
1302 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1304 bool isCOP0AsmReg() const {
1305 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1307 bool isCOP2AsmReg() const {
1308 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1310 bool isCOP3AsmReg() const {
1311 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1313 bool isMSA128AsmReg() const {
1314 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1316 bool isMSACtrlAsmReg() const {
1317 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1320 /// getStartLoc - Get the location of the first token of this operand.
1321 SMLoc getStartLoc() const override { return StartLoc; }
1322 /// getEndLoc - Get the location of the last token of this operand.
1323 SMLoc getEndLoc() const override { return EndLoc; }
1325 virtual ~MipsOperand() {
1333 delete RegList.List;
1334 case k_PhysRegister:
1335 case k_RegisterIndex:
1342 void print(raw_ostream &OS) const override {
1351 Mem.Base->print(OS);
1356 case k_PhysRegister:
1357 OS << "PhysReg<" << PhysReg.Num << ">";
1359 case k_RegisterIndex:
1360 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1367 for (auto Reg : (*RegList.List))
1372 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1376 }; // class MipsOperand
1380 extern const MCInstrDesc MipsInsts[];
1382 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1383 return MipsInsts[Opcode];
1386 static bool hasShortDelaySlot(unsigned Opcode) {
1389 case Mips::JALRS_MM:
1390 case Mips::JALRS16_MM:
1391 case Mips::BGEZALS_MM:
1392 case Mips::BLTZALS_MM:
1399 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1400 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1401 return &SRExpr->getSymbol();
1404 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1405 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1406 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1417 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1418 return getSingleMCSymbol(UExpr->getSubExpr());
1423 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1424 if (isa<MCSymbolRefExpr>(Expr))
1427 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1428 return countMCSymbolRefExpr(BExpr->getLHS()) +
1429 countMCSymbolRefExpr(BExpr->getRHS());
1431 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1432 return countMCSymbolRefExpr(UExpr->getSubExpr());
1438 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1439 SmallVectorImpl<MCInst> &Instructions) {
1441 tmpInst.setOpcode(Opcode);
1442 tmpInst.addOperand(MCOperand::createReg(Reg0));
1443 tmpInst.addOperand(Op1);
1444 tmpInst.setLoc(IDLoc);
1445 Instructions.push_back(tmpInst);
1448 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1449 SmallVectorImpl<MCInst> &Instructions) {
1450 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1453 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1454 SmallVectorImpl<MCInst> &Instructions) {
1455 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1458 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1459 SmallVectorImpl<MCInst> &Instructions) {
1461 tmpInst.setOpcode(Opcode);
1462 tmpInst.addOperand(MCOperand::createImm(Imm1));
1463 tmpInst.addOperand(MCOperand::createImm(Imm2));
1464 tmpInst.setLoc(IDLoc);
1465 Instructions.push_back(tmpInst);
1468 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1469 SmallVectorImpl<MCInst> &Instructions) {
1471 tmpInst.setOpcode(Opcode);
1472 tmpInst.addOperand(MCOperand::createReg(Reg0));
1473 tmpInst.setLoc(IDLoc);
1474 Instructions.push_back(tmpInst);
1477 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1478 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1480 tmpInst.setOpcode(Opcode);
1481 tmpInst.addOperand(MCOperand::createReg(Reg0));
1482 tmpInst.addOperand(MCOperand::createReg(Reg1));
1483 tmpInst.addOperand(Op2);
1484 tmpInst.setLoc(IDLoc);
1485 Instructions.push_back(tmpInst);
1488 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1489 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1490 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1494 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1495 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1496 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1500 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1501 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1502 if (ShiftAmount >= 32) {
1503 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1508 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1510 } // end anonymous namespace.
1512 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1513 SmallVectorImpl<MCInst> &Instructions) {
1514 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1515 bool ExpandedJalSym = false;
1519 if (MCID.isBranch() || MCID.isCall()) {
1520 const unsigned Opcode = Inst.getOpcode();
1530 assert(hasCnMips() && "instruction only valid for octeon cpus");
1537 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1538 Offset = Inst.getOperand(2);
1539 if (!Offset.isImm())
1540 break; // We'll deal with this situation later on when applying fixups.
1541 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1542 return Error(IDLoc, "branch target out of range");
1543 if (OffsetToAlignment(Offset.getImm(),
1544 1LL << (inMicroMipsMode() ? 1 : 2)))
1545 return Error(IDLoc, "branch to misaligned address");
1559 case Mips::BGEZAL_MM:
1560 case Mips::BLTZAL_MM:
1563 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1564 Offset = Inst.getOperand(1);
1565 if (!Offset.isImm())
1566 break; // We'll deal with this situation later on when applying fixups.
1567 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1568 return Error(IDLoc, "branch target out of range");
1569 if (OffsetToAlignment(Offset.getImm(),
1570 1LL << (inMicroMipsMode() ? 1 : 2)))
1571 return Error(IDLoc, "branch to misaligned address");
1573 case Mips::BEQZ16_MM:
1574 case Mips::BEQZC16_MMR6:
1575 case Mips::BNEZ16_MM:
1576 case Mips::BNEZC16_MMR6:
1577 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1578 Offset = Inst.getOperand(1);
1579 if (!Offset.isImm())
1580 break; // We'll deal with this situation later on when applying fixups.
1581 if (!isInt<8>(Offset.getImm()))
1582 return Error(IDLoc, "branch target out of range");
1583 if (OffsetToAlignment(Offset.getImm(), 2LL))
1584 return Error(IDLoc, "branch to misaligned address");
1589 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1590 // We still accept it but it is a normal nop.
1591 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1592 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1593 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1598 const unsigned Opcode = Inst.getOpcode();
1610 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1611 // The offset is handled above
1612 Opnd = Inst.getOperand(1);
1614 return Error(IDLoc, "expected immediate operand kind");
1615 Imm = Opnd.getImm();
1616 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1617 Opcode == Mips::BBIT1 ? 63 : 31))
1618 return Error(IDLoc, "immediate operand value out of range");
1620 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1622 Inst.getOperand(1).setImm(Imm - 32);
1628 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1629 Opnd = Inst.getOperand(2);
1631 return Error(IDLoc, "expected immediate operand kind");
1632 Imm = Opnd.getImm();
1633 if (!isInt<10>(Imm))
1634 return Error(IDLoc, "immediate operand value out of range");
1639 // This expansion is not in a function called by tryExpandInstruction()
1640 // because the pseudo-instruction doesn't have a distinct opcode.
1641 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1643 warnIfNoMacro(IDLoc);
1645 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1647 // We can do this expansion if there's only 1 symbol in the argument
1649 if (countMCSymbolRefExpr(JalExpr) > 1)
1650 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1652 // FIXME: This is checking the expression can be handled by the later stages
1653 // of the assembler. We ought to leave it to those later stages but
1654 // we can't do that until we stop evaluateRelocExpr() rewriting the
1655 // expressions into non-equivalent forms.
1656 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1658 // FIXME: Add support for label+offset operands (currently causes an error).
1659 // FIXME: Add support for forward-declared local symbols.
1660 // FIXME: Add expansion for when the LargeGOT option is enabled.
1661 if (JalSym->isInSection() || JalSym->isTemporary()) {
1663 // If it's a local symbol and the O32 ABI is being used, we expand to:
1665 // R_(MICRO)MIPS_GOT16 label
1666 // addiu $25, $25, 0
1667 // R_(MICRO)MIPS_LO16 label
1669 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1670 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1672 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1673 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1674 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1675 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1676 } else if (isABI_N32() || isABI_N64()) {
1677 // If it's a local symbol and the N32/N64 ABIs are being used,
1679 // lw/ld $25, 0($gp)
1680 // R_(MICRO)MIPS_GOT_DISP label
1682 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1684 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1685 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1688 // If it's an external/weak symbol, we expand to:
1689 // lw/ld $25, 0($gp)
1690 // R_(MICRO)MIPS_CALL16 label
1692 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1694 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1695 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1699 if (IsCpRestoreSet && inMicroMipsMode())
1700 JalrInst.setOpcode(Mips::JALRS_MM);
1702 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1703 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1704 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1706 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1707 // This relocation is supposed to be an optimization hint for the linker
1708 // and is not necessary for correctness.
1711 ExpandedJalSym = true;
1714 if (MCID.mayLoad() || MCID.mayStore()) {
1715 // Check the offset of memory operand, if it is a symbol
1716 // reference or immediate we may have to expand instructions.
1717 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1718 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1719 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1720 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1721 MCOperand &Op = Inst.getOperand(i);
1723 int MemOffset = Op.getImm();
1724 if (MemOffset < -32768 || MemOffset > 32767) {
1725 // Offset can't exceed 16bit value.
1726 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1729 } else if (Op.isExpr()) {
1730 const MCExpr *Expr = Op.getExpr();
1731 if (Expr->getKind() == MCExpr::SymbolRef) {
1732 const MCSymbolRefExpr *SR =
1733 static_cast<const MCSymbolRefExpr *>(Expr);
1734 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1736 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1739 } else if (!isEvaluated(Expr)) {
1740 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1748 if (inMicroMipsMode()) {
1749 if (MCID.mayLoad()) {
1750 // Try to create 16-bit GP relative load instruction.
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 MCOperand &DstReg = Inst.getOperand(0);
1759 MCOperand &BaseReg = Inst.getOperand(1);
1760 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1761 getContext().getRegisterInfo()->getRegClass(
1762 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1763 (BaseReg.getReg() == Mips::GP ||
1764 BaseReg.getReg() == Mips::GP_64)) {
1766 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1767 IDLoc, Instructions);
1775 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1780 switch (Inst.getOpcode()) {
1783 case Mips::ADDIUS5_MM:
1784 Opnd = Inst.getOperand(2);
1786 return Error(IDLoc, "expected immediate operand kind");
1787 Imm = Opnd.getImm();
1788 if (Imm < -8 || Imm > 7)
1789 return Error(IDLoc, "immediate operand value out of range");
1791 case Mips::ADDIUSP_MM:
1792 Opnd = Inst.getOperand(0);
1794 return Error(IDLoc, "expected immediate operand kind");
1795 Imm = Opnd.getImm();
1796 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1798 return Error(IDLoc, "immediate operand value out of range");
1800 case Mips::SLL16_MM:
1801 case Mips::SRL16_MM:
1802 Opnd = Inst.getOperand(2);
1804 return Error(IDLoc, "expected immediate operand kind");
1805 Imm = Opnd.getImm();
1806 if (Imm < 1 || Imm > 8)
1807 return Error(IDLoc, "immediate operand value out of range");
1810 Opnd = Inst.getOperand(1);
1812 return Error(IDLoc, "expected immediate operand kind");
1813 Imm = Opnd.getImm();
1814 if (Imm < -1 || Imm > 126)
1815 return Error(IDLoc, "immediate operand value out of range");
1817 case Mips::ADDIUR2_MM:
1818 Opnd = Inst.getOperand(2);
1820 return Error(IDLoc, "expected immediate operand kind");
1821 Imm = Opnd.getImm();
1822 if (!(Imm == 1 || Imm == -1 ||
1823 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1824 return Error(IDLoc, "immediate operand value out of range");
1826 case Mips::ADDIUR1SP_MM:
1827 Opnd = Inst.getOperand(1);
1829 return Error(IDLoc, "expected immediate operand kind");
1830 Imm = Opnd.getImm();
1831 if (OffsetToAlignment(Imm, 4LL))
1832 return Error(IDLoc, "misaligned immediate operand value");
1833 if (Imm < 0 || Imm > 255)
1834 return Error(IDLoc, "immediate operand value out of range");
1836 case Mips::ANDI16_MM:
1837 Opnd = Inst.getOperand(2);
1839 return Error(IDLoc, "expected immediate operand kind");
1840 Imm = Opnd.getImm();
1841 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1842 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1843 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1844 return Error(IDLoc, "immediate operand value out of range");
1846 case Mips::LBU16_MM:
1847 Opnd = Inst.getOperand(2);
1849 return Error(IDLoc, "expected immediate operand kind");
1850 Imm = Opnd.getImm();
1851 if (Imm < -1 || Imm > 14)
1852 return Error(IDLoc, "immediate operand value out of range");
1861 case Mips::SB16_MMR6:
1862 Opnd = Inst.getOperand(2);
1864 return Error(IDLoc, "expected immediate operand kind");
1865 Imm = Opnd.getImm();
1866 if (Imm < 0 || Imm > 15)
1867 return Error(IDLoc, "immediate operand value out of range");
1869 case Mips::LHU16_MM:
1871 case Mips::SH16_MMR6:
1872 Opnd = Inst.getOperand(2);
1874 return Error(IDLoc, "expected immediate operand kind");
1875 Imm = Opnd.getImm();
1876 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1877 return Error(IDLoc, "immediate operand value out of range");
1881 case Mips::SW16_MMR6:
1882 Opnd = Inst.getOperand(2);
1884 return Error(IDLoc, "expected immediate operand kind");
1885 Imm = Opnd.getImm();
1886 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1887 return Error(IDLoc, "immediate operand value out of range");
1889 case Mips::ADDIUPC_MM:
1890 MCOperand Opnd = Inst.getOperand(1);
1892 return Error(IDLoc, "expected immediate operand kind");
1893 int Imm = Opnd.getImm();
1894 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1895 return Error(IDLoc, "immediate operand value out of range");
1900 MacroExpanderResultTy ExpandResult =
1901 tryExpandInstruction(Inst, IDLoc, Instructions);
1902 switch (ExpandResult) {
1904 Instructions.push_back(Inst);
1912 // If this instruction has a delay slot and .set reorder is active,
1913 // emit a NOP after it.
1914 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1915 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1917 if ((Inst.getOpcode() == Mips::JalOneReg ||
1918 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1919 isPicAndNotNxxAbi()) {
1920 if (IsCpRestoreSet) {
1921 // We need a NOP between the JALR and the LW:
1922 // If .set reorder has been used, we've already emitted a NOP.
1923 // If .set noreorder has been used, we need to emit a NOP at this point.
1924 if (!AssemblerOptions.back()->isReorder())
1925 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1927 // Load the $gp from the stack.
1928 SmallVector<MCInst, 3> LoadInsts;
1929 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1932 for (const MCInst &Inst : LoadInsts)
1933 Instructions.push_back(Inst);
1936 Warning(IDLoc, "no .cprestore used in PIC mode");
1942 MipsAsmParser::MacroExpanderResultTy
1943 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
1944 SmallVectorImpl<MCInst> &Instructions) {
1945 switch (Inst.getOpcode()) {
1947 return MER_NotAMacro;
1948 case Mips::LoadImm32:
1949 return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
1951 case Mips::LoadImm64:
1952 return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
1954 case Mips::LoadAddrImm32:
1955 case Mips::LoadAddrImm64:
1956 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1957 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1958 "expected immediate operand kind");
1960 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
1962 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1966 case Mips::LoadAddrReg32:
1967 case Mips::LoadAddrReg64:
1968 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1969 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1970 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1971 "expected immediate operand kind");
1973 return expandLoadAddress(Inst.getOperand(0).getReg(),
1974 Inst.getOperand(1).getReg(), Inst.getOperand(2),
1975 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
1979 case Mips::B_MM_Pseudo:
1980 case Mips::B_MMR6_Pseudo:
1981 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
1985 return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
1987 case Mips::JalOneReg:
1988 case Mips::JalTwoReg:
1989 return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
1993 return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2010 case Mips::BLTImmMacro:
2011 case Mips::BLEImmMacro:
2012 case Mips::BGEImmMacro:
2013 case Mips::BGTImmMacro:
2014 case Mips::BLTUImmMacro:
2015 case Mips::BLEUImmMacro:
2016 case Mips::BGEUImmMacro:
2017 case Mips::BGTUImmMacro:
2018 case Mips::BLTLImmMacro:
2019 case Mips::BLELImmMacro:
2020 case Mips::BGELImmMacro:
2021 case Mips::BGTLImmMacro:
2022 case Mips::BLTULImmMacro:
2023 case Mips::BLEULImmMacro:
2024 case Mips::BGEULImmMacro:
2025 case Mips::BGTULImmMacro:
2026 return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2028 case Mips::SDivMacro:
2029 return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2031 case Mips::DSDivMacro:
2032 return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2034 case Mips::UDivMacro:
2035 return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2037 case Mips::DUDivMacro:
2038 return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2041 return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2043 return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2045 return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2047 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2053 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2054 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2055 int64_t ImmValue = Inst.getOperand(2).getImm();
2056 if (isInt<16>(ImmValue))
2057 return MER_NotAMacro;
2058 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2061 return MER_NotAMacro;
2065 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2066 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2067 int64_t ImmValue = Inst.getOperand(2).getImm();
2068 if (isUInt<16>(ImmValue))
2069 return MER_NotAMacro;
2070 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2073 return MER_NotAMacro;
2076 return expandRotation(Inst, IDLoc, Instructions) ? MER_Fail
2080 return expandRotationImm(Inst, IDLoc, Instructions) ? MER_Fail
2084 return expandDRotation(Inst, IDLoc, Instructions) ? MER_Fail
2088 return expandDRotationImm(Inst, IDLoc, Instructions) ? MER_Fail
2093 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2094 SmallVectorImpl<MCInst> &Instructions) {
2095 // Create a JALR instruction which is going to replace the pseudo-JAL.
2097 JalrInst.setLoc(IDLoc);
2098 const MCOperand FirstRegOp = Inst.getOperand(0);
2099 const unsigned Opcode = Inst.getOpcode();
2101 if (Opcode == Mips::JalOneReg) {
2102 // jal $rs => jalr $rs
2103 if (IsCpRestoreSet && inMicroMipsMode()) {
2104 JalrInst.setOpcode(Mips::JALRS16_MM);
2105 JalrInst.addOperand(FirstRegOp);
2106 } else if (inMicroMipsMode()) {
2107 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2108 JalrInst.addOperand(FirstRegOp);
2110 JalrInst.setOpcode(Mips::JALR);
2111 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2112 JalrInst.addOperand(FirstRegOp);
2114 } else if (Opcode == Mips::JalTwoReg) {
2115 // jal $rd, $rs => jalr $rd, $rs
2116 if (IsCpRestoreSet && inMicroMipsMode())
2117 JalrInst.setOpcode(Mips::JALRS_MM);
2119 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2120 JalrInst.addOperand(FirstRegOp);
2121 const MCOperand SecondRegOp = Inst.getOperand(1);
2122 JalrInst.addOperand(SecondRegOp);
2124 Instructions.push_back(JalrInst);
2126 // If .set reorder is active and branch instruction has a delay slot,
2127 // emit a NOP after it.
2128 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2129 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2130 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2136 /// Can the value be represented by a unsigned N-bit value and a shift left?
2137 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2138 unsigned BitNum = findFirstSet(x);
2140 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2143 /// Load (or add) an immediate into a register.
2145 /// @param ImmValue The immediate to load.
2146 /// @param DstReg The register that will hold the immediate.
2147 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2148 /// for a simple initialization.
2149 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2150 /// @param IsAddress True if the immediate represents an address. False if it
2152 /// @param IDLoc Location of the immediate in the source file.
2153 /// @param Instructions The instructions emitted by this expansion.
2154 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2155 unsigned SrcReg, bool Is32BitImm,
2156 bool IsAddress, SMLoc IDLoc,
2157 SmallVectorImpl<MCInst> &Instructions) {
2158 if (!Is32BitImm && !isGP64bit()) {
2159 Error(IDLoc, "instruction requires a 64-bit architecture");
2164 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2165 // Sign extend up to 64-bit so that the predicates match the hardware
2166 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2168 ImmValue = SignExtend64<32>(ImmValue);
2170 Error(IDLoc, "instruction requires a 32-bit immediate");
2175 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2176 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2178 bool UseSrcReg = false;
2179 if (SrcReg != Mips::NoRegister)
2182 unsigned TmpReg = DstReg;
2183 if (UseSrcReg && (DstReg == SrcReg)) {
2184 // At this point we need AT to perform the expansions and we exit if it is
2186 unsigned ATReg = getATReg(IDLoc);
2192 if (isInt<16>(ImmValue)) {
2196 // This doesn't quite follow the usual ABI expectations for N32 but matches
2197 // traditional assembler behaviour. N32 would normally use addiu for both
2198 // integers and addresses.
2199 if (IsAddress && !Is32BitImm) {
2200 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2204 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2208 if (isUInt<16>(ImmValue)) {
2209 unsigned TmpReg = DstReg;
2210 if (SrcReg == DstReg) {
2211 TmpReg = getATReg(IDLoc);
2216 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2218 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2222 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2223 warnIfNoMacro(IDLoc);
2225 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2226 uint16_t Bits15To0 = ImmValue & 0xffff;
2228 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2229 // Traditional behaviour seems to special case this particular value. It's
2230 // not clear why other masks are handled differently.
2231 if (ImmValue == 0xffffffff) {
2232 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2233 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2235 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2239 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2241 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2242 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2244 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2246 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2250 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2252 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2254 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2258 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2260 Error(IDLoc, "instruction requires a 32-bit immediate");
2264 // Traditionally, these immediates are shifted as little as possible and as
2265 // such we align the most significant bit to bit 15 of our temporary.
2266 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2267 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2268 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2269 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2270 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2271 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2274 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2279 warnIfNoMacro(IDLoc);
2281 // The remaining case is packed with a sequence of dsll and ori with zeros
2282 // being omitted and any neighbouring dsll's being coalesced.
2283 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2285 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2286 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2287 IDLoc, Instructions))
2290 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2291 // skip it and defer the shift to the next chunk.
2292 unsigned ShiftCarriedForwards = 16;
2293 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2294 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2296 if (ImmChunk != 0) {
2297 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2299 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2300 ShiftCarriedForwards = 0;
2303 ShiftCarriedForwards += 16;
2305 ShiftCarriedForwards -= 16;
2307 // Finish any remaining shifts left by trailing zeros.
2308 if (ShiftCarriedForwards)
2309 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2313 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2318 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2319 SmallVectorImpl<MCInst> &Instructions) {
2320 const MCOperand &ImmOp = Inst.getOperand(1);
2321 assert(ImmOp.isImm() && "expected immediate operand kind");
2322 const MCOperand &DstRegOp = Inst.getOperand(0);
2323 assert(DstRegOp.isReg() && "expected register operand kind");
2325 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2326 Is32BitImm, false, IDLoc, Instructions))
2332 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2333 const MCOperand &Offset,
2334 bool Is32BitAddress, SMLoc IDLoc,
2335 SmallVectorImpl<MCInst> &Instructions) {
2336 // la can't produce a usable address when addresses are 64-bit.
2337 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2338 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2339 // We currently can't do this because we depend on the equality
2340 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2341 Error(IDLoc, "la used to load 64-bit address");
2342 // Continue as if we had 'dla' instead.
2343 Is32BitAddress = false;
2346 // dla requires 64-bit addresses.
2347 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2348 Error(IDLoc, "instruction requires a 64-bit architecture");
2352 if (!Offset.isImm())
2353 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2354 Is32BitAddress, IDLoc, Instructions);
2356 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2357 IDLoc, Instructions);
2360 bool MipsAsmParser::loadAndAddSymbolAddress(
2361 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2362 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2363 warnIfNoMacro(IDLoc);
2365 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2366 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2367 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2368 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2369 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2371 bool UseSrcReg = SrcReg != Mips::NoRegister;
2373 // This is the 64-bit symbol address expansion.
2374 if (ABI.ArePtrs64bit() && isGP64bit()) {
2375 // We always need AT for the 64-bit expansion.
2376 // If it is not available we exit.
2377 unsigned ATReg = getATReg(IDLoc);
2381 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2382 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2383 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2384 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2386 if (UseSrcReg && (DstReg == SrcReg)) {
2387 // If $rs is the same as $rd:
2388 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2389 // daddiu $at, $at, %higher(sym)
2390 // dsll $at, $at, 16
2391 // daddiu $at, $at, %hi(sym)
2392 // dsll $at, $at, 16
2393 // daddiu $at, $at, %lo(sym)
2394 // daddu $rd, $at, $rd
2395 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2397 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2398 IDLoc, Instructions);
2399 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2400 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2402 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2403 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2405 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2410 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2411 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2412 // lui $at, %hi(sym)
2413 // daddiu $rd, $rd, %higher(sym)
2414 // daddiu $at, $at, %lo(sym)
2415 // dsll32 $rd, $rd, 0
2416 // daddu $rd, $rd, $at
2417 // (daddu $rd, $rd, $rs)
2418 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2420 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2422 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2423 IDLoc, Instructions);
2424 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2426 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2427 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2429 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2434 // And now, the 32-bit symbol address expansion:
2435 // If $rs is the same as $rd:
2436 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2437 // ori $at, $at, %lo(sym)
2438 // addu $rd, $at, $rd
2439 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2440 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2441 // ori $rd, $rd, %lo(sym)
2442 // (addu $rd, $rd, $rs)
2443 unsigned TmpReg = DstReg;
2444 if (UseSrcReg && (DstReg == SrcReg)) {
2445 // If $rs is the same as $rd, we need to use AT.
2446 // If it is not available we exit.
2447 unsigned ATReg = getATReg(IDLoc);
2453 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2454 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2458 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2460 assert(DstReg == TmpReg);
2465 bool MipsAsmParser::expandUncondBranchMMPseudo(
2466 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2467 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2468 "unexpected number of operands");
2470 MCOperand Offset = Inst.getOperand(0);
2471 if (Offset.isExpr()) {
2473 Inst.setOpcode(Mips::BEQ_MM);
2474 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2475 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2476 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2478 assert(Offset.isImm() && "expected immediate operand kind");
2479 if (isInt<11>(Offset.getImm())) {
2480 // If offset fits into 11 bits then this instruction becomes microMIPS
2481 // 16-bit unconditional branch instruction.
2482 if (inMicroMipsMode())
2483 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2485 if (!isInt<17>(Offset.getImm()))
2486 Error(IDLoc, "branch target out of range");
2487 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2488 Error(IDLoc, "branch to misaligned address");
2490 Inst.setOpcode(Mips::BEQ_MM);
2491 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2492 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2493 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2496 Instructions.push_back(Inst);
2498 // If .set reorder is active and branch instruction has a delay slot,
2499 // emit a NOP after it.
2500 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2501 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2502 createNop(true, IDLoc, Instructions);
2507 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2508 SmallVectorImpl<MCInst> &Instructions) {
2509 const MCOperand &DstRegOp = Inst.getOperand(0);
2510 assert(DstRegOp.isReg() && "expected register operand kind");
2512 const MCOperand &ImmOp = Inst.getOperand(1);
2513 assert(ImmOp.isImm() && "expected immediate operand kind");
2515 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2516 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2518 unsigned OpCode = 0;
2519 switch(Inst.getOpcode()) {
2527 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2531 int64_t ImmValue = ImmOp.getImm();
2533 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2536 warnIfNoMacro(IDLoc);
2538 unsigned ATReg = getATReg(IDLoc);
2542 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2543 IDLoc, Instructions))
2546 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2551 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2552 SmallVectorImpl<MCInst> &Instructions,
2553 bool isLoad, bool isImmOpnd) {
2554 unsigned ImmOffset, HiOffset, LoOffset;
2555 const MCExpr *ExprOffset;
2557 // 1st operand is either the source or destination register.
2558 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2559 unsigned RegOpNum = Inst.getOperand(0).getReg();
2560 // 2nd operand is the base register.
2561 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2562 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2563 // 3rd operand is either an immediate or expression.
2565 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2566 ImmOffset = Inst.getOperand(2).getImm();
2567 LoOffset = ImmOffset & 0x0000ffff;
2568 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2569 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2570 if (LoOffset & 0x8000)
2573 ExprOffset = Inst.getOperand(2).getExpr();
2574 // These are some of the types of expansions we perform here:
2575 // 1) lw $8, sym => lui $8, %hi(sym)
2576 // lw $8, %lo(sym)($8)
2577 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2579 // lw $8, %lo(offset)($9)
2580 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2582 // lw $8, %lo(offset)($at)
2583 // 4) sw $8, sym => lui $at, %hi(sym)
2584 // sw $8, %lo(sym)($at)
2585 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2587 // sw $8, %lo(offset)($at)
2588 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2589 // ldc1 $f0, %lo(sym)($at)
2591 // For load instructions we can use the destination register as a temporary
2592 // if base and dst are different (examples 1 and 2) and if the base register
2593 // is general purpose otherwise we must use $at (example 6) and error if it's
2594 // not available. For stores we must use $at (examples 4 and 5) because we
2595 // must not clobber the source register setting up the offset.
2596 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2597 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2598 unsigned RegClassIDOp0 =
2599 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2600 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2601 (RegClassIDOp0 == Mips::GPR64RegClassID);
2602 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2603 TmpRegNum = RegOpNum;
2605 // At this point we need AT to perform the expansions and we exit if it is
2607 TmpRegNum = getATReg(IDLoc);
2612 emitRX(Mips::LUi, TmpRegNum,
2613 isImmOpnd ? MCOperand::createImm(HiOffset)
2614 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2615 IDLoc, Instructions);
2616 // Add temp register to base.
2617 if (BaseRegNum != Mips::ZERO)
2618 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2619 // And finally, create original instruction with low part
2620 // of offset and new base.
2621 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2623 ? MCOperand::createImm(LoOffset)
2624 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2625 IDLoc, Instructions);
2629 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2630 SmallVectorImpl<MCInst> &Instructions) {
2631 unsigned OpNum = Inst.getNumOperands();
2632 unsigned Opcode = Inst.getOpcode();
2633 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2635 assert (Inst.getOperand(OpNum - 1).isImm() &&
2636 Inst.getOperand(OpNum - 2).isReg() &&
2637 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2639 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2640 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2641 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2642 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2643 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2644 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2645 // It can be implemented as SWM16 or LWM16 instruction.
2646 if (inMicroMipsMode() && hasMips32r6())
2647 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2649 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2652 Inst.setOpcode(NewOpcode);
2653 Instructions.push_back(Inst);
2657 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2658 SmallVectorImpl<MCInst> &Instructions) {
2659 bool EmittedNoMacroWarning = false;
2660 unsigned PseudoOpcode = Inst.getOpcode();
2661 unsigned SrcReg = Inst.getOperand(0).getReg();
2662 const MCOperand &TrgOp = Inst.getOperand(1);
2663 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2665 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2666 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2670 TrgReg = TrgOp.getReg();
2671 else if (TrgOp.isImm()) {
2672 warnIfNoMacro(IDLoc);
2673 EmittedNoMacroWarning = true;
2675 TrgReg = getATReg(IDLoc);
2679 switch(PseudoOpcode) {
2681 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2682 case Mips::BLTImmMacro:
2683 PseudoOpcode = Mips::BLT;
2685 case Mips::BLEImmMacro:
2686 PseudoOpcode = Mips::BLE;
2688 case Mips::BGEImmMacro:
2689 PseudoOpcode = Mips::BGE;
2691 case Mips::BGTImmMacro:
2692 PseudoOpcode = Mips::BGT;
2694 case Mips::BLTUImmMacro:
2695 PseudoOpcode = Mips::BLTU;
2697 case Mips::BLEUImmMacro:
2698 PseudoOpcode = Mips::BLEU;
2700 case Mips::BGEUImmMacro:
2701 PseudoOpcode = Mips::BGEU;
2703 case Mips::BGTUImmMacro:
2704 PseudoOpcode = Mips::BGTU;
2706 case Mips::BLTLImmMacro:
2707 PseudoOpcode = Mips::BLTL;
2709 case Mips::BLELImmMacro:
2710 PseudoOpcode = Mips::BLEL;
2712 case Mips::BGELImmMacro:
2713 PseudoOpcode = Mips::BGEL;
2715 case Mips::BGTLImmMacro:
2716 PseudoOpcode = Mips::BGTL;
2718 case Mips::BLTULImmMacro:
2719 PseudoOpcode = Mips::BLTUL;
2721 case Mips::BLEULImmMacro:
2722 PseudoOpcode = Mips::BLEUL;
2724 case Mips::BGEULImmMacro:
2725 PseudoOpcode = Mips::BGEUL;
2727 case Mips::BGTULImmMacro:
2728 PseudoOpcode = Mips::BGTUL;
2732 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2733 false, IDLoc, Instructions))
2737 switch (PseudoOpcode) {
2742 AcceptsEquality = false;
2743 ReverseOrderSLT = false;
2744 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2745 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2746 ZeroSrcOpcode = Mips::BGTZ;
2747 ZeroTrgOpcode = Mips::BLTZ;
2753 AcceptsEquality = true;
2754 ReverseOrderSLT = true;
2755 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2756 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2757 ZeroSrcOpcode = Mips::BGEZ;
2758 ZeroTrgOpcode = Mips::BLEZ;
2764 AcceptsEquality = true;
2765 ReverseOrderSLT = false;
2766 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2767 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2768 ZeroSrcOpcode = Mips::BLEZ;
2769 ZeroTrgOpcode = Mips::BGEZ;
2775 AcceptsEquality = false;
2776 ReverseOrderSLT = true;
2777 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2778 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2779 ZeroSrcOpcode = Mips::BLTZ;
2780 ZeroTrgOpcode = Mips::BGTZ;
2783 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2786 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2787 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2788 if (IsSrcRegZero && IsTrgRegZero) {
2789 // FIXME: All of these Opcode-specific if's are needed for compatibility
2790 // with GAS' behaviour. However, they may not generate the most efficient
2791 // code in some circumstances.
2792 if (PseudoOpcode == Mips::BLT) {
2793 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2797 if (PseudoOpcode == Mips::BLE) {
2798 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2800 Warning(IDLoc, "branch is always taken");
2803 if (PseudoOpcode == Mips::BGE) {
2804 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2806 Warning(IDLoc, "branch is always taken");
2809 if (PseudoOpcode == Mips::BGT) {
2810 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2814 if (PseudoOpcode == Mips::BGTU) {
2815 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2816 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2819 if (AcceptsEquality) {
2820 // If both registers are $0 and the pseudo-branch accepts equality, it
2821 // will always be taken, so we emit an unconditional branch.
2822 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2823 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2824 Warning(IDLoc, "branch is always taken");
2827 // If both registers are $0 and the pseudo-branch does not accept
2828 // equality, it will never be taken, so we don't have to emit anything.
2831 if (IsSrcRegZero || IsTrgRegZero) {
2832 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2833 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2834 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2835 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2836 // the pseudo-branch will never be taken, so we don't emit anything.
2837 // This only applies to unsigned pseudo-branches.
2840 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2841 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2842 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2843 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2844 // the pseudo-branch will always be taken, so we emit an unconditional
2846 // This only applies to unsigned pseudo-branches.
2847 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2848 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2849 Warning(IDLoc, "branch is always taken");
2853 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2854 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2855 // the pseudo-branch will be taken only when the non-zero register is
2856 // different from 0, so we emit a BNEZ.
2858 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2859 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2860 // the pseudo-branch will be taken only when the non-zero register is
2861 // equal to 0, so we emit a BEQZ.
2863 // Because only BLEU and BGEU branch on equality, we can use the
2864 // AcceptsEquality variable to decide when to emit the BEQZ.
2865 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2866 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2867 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2870 // If we have a signed pseudo-branch and one of the registers is $0,
2871 // we can use an appropriate compare-to-zero branch. We select which one
2872 // to use in the switch statement above.
2873 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2874 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2875 IDLoc, Instructions);
2879 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2880 // expansions. If it is not available, we return.
2881 unsigned ATRegNum = getATReg(IDLoc);
2885 if (!EmittedNoMacroWarning)
2886 warnIfNoMacro(IDLoc);
2888 // SLT fits well with 2 of our 4 pseudo-branches:
2889 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2890 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2891 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2892 // This is accomplished by using a BNEZ with the result of the SLT.
2894 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2895 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2896 // Because only BGE and BLE branch on equality, we can use the
2897 // AcceptsEquality variable to decide when to emit the BEQZ.
2898 // Note that the order of the SLT arguments doesn't change between
2901 // The same applies to the unsigned variants, except that SLTu is used
2903 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2904 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2905 IDLoc, Instructions);
2907 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2908 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2909 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2914 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2915 SmallVectorImpl<MCInst> &Instructions,
2916 const bool IsMips64, const bool Signed) {
2917 if (hasMips32r6()) {
2918 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2922 warnIfNoMacro(IDLoc);
2924 const MCOperand &RsRegOp = Inst.getOperand(0);
2925 assert(RsRegOp.isReg() && "expected register operand kind");
2926 unsigned RsReg = RsRegOp.getReg();
2928 const MCOperand &RtRegOp = Inst.getOperand(1);
2929 assert(RtRegOp.isReg() && "expected register operand kind");
2930 unsigned RtReg = RtRegOp.getReg();
2935 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2936 ZeroReg = Mips::ZERO_64;
2938 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2939 ZeroReg = Mips::ZERO;
2942 bool UseTraps = useTraps();
2944 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2945 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2946 Warning(IDLoc, "dividing zero by zero");
2948 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2950 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2954 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2958 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2963 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2964 Warning(IDLoc, "division by zero");
2967 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2971 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2976 // FIXME: The values for these two BranchTarget variables may be different in
2977 // micromips. These magic numbers need to be removed.
2978 unsigned BranchTargetNoTraps;
2979 unsigned BranchTarget;
2982 BranchTarget = IsMips64 ? 12 : 8;
2983 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2985 BranchTarget = IsMips64 ? 20 : 16;
2986 BranchTargetNoTraps = 8;
2987 // Branch to the li instruction.
2988 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2992 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2995 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2998 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3002 unsigned ATReg = getATReg(IDLoc);
3006 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
3008 // Branch to the mflo instruction.
3009 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3010 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
3011 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
3013 // Branch to the mflo instruction.
3014 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3015 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
3019 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
3021 // Branch to the mflo instruction.
3022 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
3023 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
3024 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
3026 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3030 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3031 SmallVectorImpl<MCInst> &Instructions) {
3032 if (hasMips32r6() || hasMips64r6()) {
3033 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3037 warnIfNoMacro(IDLoc);
3039 const MCOperand &DstRegOp = Inst.getOperand(0);
3040 assert(DstRegOp.isReg() && "expected register operand kind");
3042 const MCOperand &SrcRegOp = Inst.getOperand(1);
3043 assert(SrcRegOp.isReg() && "expected register operand kind");
3045 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3046 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3048 unsigned DstReg = DstRegOp.getReg();
3049 unsigned SrcReg = SrcRegOp.getReg();
3050 int64_t OffsetValue = OffsetImmOp.getImm();
3052 // NOTE: We always need AT for ULHU, as it is always used as the source
3053 // register for one of the LBu's.
3054 unsigned ATReg = getATReg(IDLoc);
3058 // When the value of offset+1 does not fit in 16 bits, we have to load the
3059 // offset in AT, (D)ADDu the original source register (if there was one), and
3060 // then use AT as the source register for the 2 generated LBu's.
3061 bool LoadedOffsetInAT = false;
3062 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3063 LoadedOffsetInAT = true;
3065 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3066 true, IDLoc, Instructions))
3069 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3070 // because it will make our output more similar to GAS'. For example,
3071 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3072 // instead of just an "ori $1, $9, 32768".
3073 // NOTE: If there is no source register specified in the ULHU, the parser
3074 // will interpret it as $0.
3075 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3076 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3079 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3080 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3081 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3083 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3085 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3086 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3088 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3089 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3092 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3094 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3095 FirstLbuOffset, IDLoc, Instructions);
3097 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3100 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3102 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3107 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3108 SmallVectorImpl<MCInst> &Instructions) {
3109 if (hasMips32r6() || hasMips64r6()) {
3110 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3114 const MCOperand &DstRegOp = Inst.getOperand(0);
3115 assert(DstRegOp.isReg() && "expected register operand kind");
3117 const MCOperand &SrcRegOp = Inst.getOperand(1);
3118 assert(SrcRegOp.isReg() && "expected register operand kind");
3120 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3121 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3123 unsigned SrcReg = SrcRegOp.getReg();
3124 int64_t OffsetValue = OffsetImmOp.getImm();
3127 // When the value of offset+3 does not fit in 16 bits, we have to load the
3128 // offset in AT, (D)ADDu the original source register (if there was one), and
3129 // then use AT as the source register for the generated LWL and LWR.
3130 bool LoadedOffsetInAT = false;
3131 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3132 ATReg = getATReg(IDLoc);
3135 LoadedOffsetInAT = true;
3137 warnIfNoMacro(IDLoc);
3139 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3140 true, IDLoc, Instructions))
3143 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3144 // because it will make our output more similar to GAS'. For example,
3145 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3146 // instead of just an "ori $1, $9, 32768".
3147 // NOTE: If there is no source register specified in the ULW, the parser
3148 // will interpret it as $0.
3149 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3150 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3153 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3154 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3156 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3157 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3159 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3160 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3163 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3166 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3172 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3173 SmallVectorImpl<MCInst> &Instructions) {
3175 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3176 assert (Inst.getOperand(0).isReg() &&
3177 Inst.getOperand(1).isReg() &&
3178 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3180 unsigned ATReg = Mips::NoRegister;
3181 unsigned FinalDstReg = Mips::NoRegister;
3182 unsigned DstReg = Inst.getOperand(0).getReg();
3183 unsigned SrcReg = Inst.getOperand(1).getReg();
3184 int64_t ImmValue = Inst.getOperand(2).getImm();
3186 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3188 unsigned FinalOpcode = Inst.getOpcode();
3190 if (DstReg == SrcReg) {
3191 ATReg = getATReg(Inst.getLoc());
3194 FinalDstReg = DstReg;
3198 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3199 switch (FinalOpcode) {
3201 llvm_unreachable("unimplemented expansion");
3203 FinalOpcode = Mips::ADD;
3206 FinalOpcode = Mips::ADDu;
3209 FinalOpcode = Mips::AND;
3211 case (Mips::NORImm):
3212 FinalOpcode = Mips::NOR;
3215 FinalOpcode = Mips::OR;
3218 FinalOpcode = Mips::SLT;
3221 FinalOpcode = Mips::SLTu;
3224 FinalOpcode = Mips::XOR;
3228 if (FinalDstReg == Mips::NoRegister)
3229 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3231 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3238 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc,
3239 SmallVectorImpl<MCInst> &Instructions) {
3240 unsigned ATReg = Mips::NoRegister;
3241 unsigned DReg = Inst.getOperand(0).getReg();
3242 unsigned SReg = Inst.getOperand(1).getReg();
3243 unsigned TReg = Inst.getOperand(2).getReg();
3244 unsigned TmpReg = DReg;
3246 unsigned FirstShift = Mips::NOP;
3247 unsigned SecondShift = Mips::NOP;
3249 if (hasMips32r2()) {
3252 TmpReg = getATReg(Inst.getLoc());
3257 if (Inst.getOpcode() == Mips::ROL) {
3258 emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3259 emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Instructions);
3263 if (Inst.getOpcode() == Mips::ROR) {
3264 emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3273 switch (Inst.getOpcode()) {
3275 llvm_unreachable("unexpected instruction opcode");
3277 FirstShift = Mips::SRLV;
3278 SecondShift = Mips::SLLV;
3281 FirstShift = Mips::SLLV;
3282 SecondShift = Mips::SRLV;
3286 ATReg = getATReg(Inst.getLoc());
3290 emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3291 emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Instructions);
3292 emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3293 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3301 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3302 SmallVectorImpl<MCInst> &Instructions) {
3304 unsigned ATReg = Mips::NoRegister;
3305 unsigned DReg = Inst.getOperand(0).getReg();
3306 unsigned SReg = Inst.getOperand(1).getReg();
3307 int64_t ImmValue = Inst.getOperand(2).getImm();
3309 unsigned FirstShift = Mips::NOP;
3310 unsigned SecondShift = Mips::NOP;
3312 if (hasMips32r2()) {
3314 if (Inst.getOpcode() == Mips::ROLImm) {
3315 uint64_t MaxShift = 32;
3316 uint64_t ShiftValue = ImmValue;
3318 ShiftValue = MaxShift - ImmValue;
3319 emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), Instructions);
3323 if (Inst.getOpcode() == Mips::RORImm) {
3324 emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), Instructions);
3333 if (ImmValue == 0) {
3334 emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), Instructions);
3338 switch (Inst.getOpcode()) {
3340 llvm_unreachable("unexpected instruction opcode");
3342 FirstShift = Mips::SLL;
3343 SecondShift = Mips::SRL;
3346 FirstShift = Mips::SRL;
3347 SecondShift = Mips::SLL;
3351 ATReg = getATReg(Inst.getLoc());
3355 emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), Instructions);
3356 emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), Instructions);
3357 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3365 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc,
3366 SmallVectorImpl<MCInst> &Instructions) {
3368 unsigned ATReg = Mips::NoRegister;
3369 unsigned DReg = Inst.getOperand(0).getReg();
3370 unsigned SReg = Inst.getOperand(1).getReg();
3371 unsigned TReg = Inst.getOperand(2).getReg();
3372 unsigned TmpReg = DReg;
3374 unsigned FirstShift = Mips::NOP;
3375 unsigned SecondShift = Mips::NOP;
3377 if (hasMips64r2()) {
3379 if (TmpReg == SReg) {
3380 TmpReg = getATReg(Inst.getLoc());
3385 if (Inst.getOpcode() == Mips::DROL) {
3386 emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3387 emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Instructions);
3391 if (Inst.getOpcode() == Mips::DROR) {
3392 emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3401 switch (Inst.getOpcode()) {
3403 llvm_unreachable("unexpected instruction opcode");
3405 FirstShift = Mips::DSRLV;
3406 SecondShift = Mips::DSLLV;
3409 FirstShift = Mips::DSLLV;
3410 SecondShift = Mips::DSRLV;
3414 ATReg = getATReg(Inst.getLoc());
3418 emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3419 emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Instructions);
3420 emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3421 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3429 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
3430 SmallVectorImpl<MCInst> &Instructions) {
3432 unsigned ATReg = Mips::NoRegister;
3433 unsigned DReg = Inst.getOperand(0).getReg();
3434 unsigned SReg = Inst.getOperand(1).getReg();
3435 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
3437 unsigned FirstShift = Mips::NOP;
3438 unsigned SecondShift = Mips::NOP;
3442 if (hasMips64r2()) {
3444 unsigned FinalOpcode = Mips::NOP;
3446 FinalOpcode = Mips::DROTR;
3447 else if (ImmValue % 32 == 0)
3448 FinalOpcode = Mips::DROTR32;
3449 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3450 if (Inst.getOpcode() == Mips::DROLImm)
3451 FinalOpcode = Mips::DROTR32;
3453 FinalOpcode = Mips::DROTR;
3454 } else if (ImmValue >= 33) {
3455 if (Inst.getOpcode() == Mips::DROLImm)
3456 FinalOpcode = Mips::DROTR;
3458 FinalOpcode = Mips::DROTR32;
3461 uint64_t ShiftValue = ImmValue % 32;
3462 if (Inst.getOpcode() == Mips::DROLImm)
3463 ShiftValue = (32 - ImmValue % 32) % 32;
3465 emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), Instructions);
3472 if (ImmValue == 0) {
3473 emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), Instructions);
3477 switch (Inst.getOpcode()) {
3479 llvm_unreachable("unexpected instruction opcode");
3481 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3482 FirstShift = Mips::DSLL;
3483 SecondShift = Mips::DSRL32;
3485 if (ImmValue == 32) {
3486 FirstShift = Mips::DSLL32;
3487 SecondShift = Mips::DSRL32;
3489 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3490 FirstShift = Mips::DSLL32;
3491 SecondShift = Mips::DSRL;
3495 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3496 FirstShift = Mips::DSRL;
3497 SecondShift = Mips::DSLL32;
3499 if (ImmValue == 32) {
3500 FirstShift = Mips::DSRL32;
3501 SecondShift = Mips::DSLL32;
3503 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3504 FirstShift = Mips::DSRL32;
3505 SecondShift = Mips::DSLL;
3510 ATReg = getATReg(Inst.getLoc());
3514 emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), Instructions);
3515 emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32, Inst.getLoc(), Instructions);
3516 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3524 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3525 SmallVectorImpl<MCInst> &Instructions) {
3526 if (hasShortDelaySlot)
3527 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3529 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3532 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3533 unsigned TrgReg, bool Is64Bit,
3534 SmallVectorImpl<MCInst> &Instructions) {
3535 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3539 void MipsAsmParser::createCpRestoreMemOp(
3540 bool IsLoad, int StackOffset, SMLoc IDLoc,
3541 SmallVectorImpl<MCInst> &Instructions) {
3542 // If the offset can not fit into 16 bits, we need to expand.
3543 if (!isInt<16>(StackOffset)) {
3545 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3546 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3547 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3548 MemInst.addOperand(MCOperand::createImm(StackOffset));
3549 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3553 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3557 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3558 // As described by the Mips32r2 spec, the registers Rd and Rs for
3559 // jalr.hb must be different.
3560 unsigned Opcode = Inst.getOpcode();
3562 if (Opcode == Mips::JALR_HB &&
3563 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3564 return Match_RequiresDifferentSrcAndDst;
3566 return Match_Success;
3569 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3570 uint64_t ErrorInfo) {
3571 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3572 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3573 if (ErrorLoc == SMLoc())
3580 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3581 OperandVector &Operands,
3583 uint64_t &ErrorInfo,
3584 bool MatchingInlineAsm) {
3587 SmallVector<MCInst, 8> Instructions;
3588 unsigned MatchResult =
3589 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3591 switch (MatchResult) {
3592 case Match_Success: {
3593 if (processInstruction(Inst, IDLoc, Instructions))
3595 for (unsigned i = 0; i < Instructions.size(); i++)
3596 Out.EmitInstruction(Instructions[i], getSTI());
3599 case Match_MissingFeature:
3600 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3602 case Match_InvalidOperand: {
3603 SMLoc ErrorLoc = IDLoc;
3604 if (ErrorInfo != ~0ULL) {
3605 if (ErrorInfo >= Operands.size())
3606 return Error(IDLoc, "too few operands for instruction");
3608 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3609 if (ErrorLoc == SMLoc())
3613 return Error(ErrorLoc, "invalid operand for instruction");
3615 case Match_MnemonicFail:
3616 return Error(IDLoc, "invalid instruction");
3617 case Match_RequiresDifferentSrcAndDst:
3618 return Error(IDLoc, "source and destination must be different");
3620 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3622 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3623 "expected 1-bit unsigned immediate");
3625 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3626 "expected 2-bit unsigned immediate");
3628 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3629 "expected immediate in range 1 .. 4");
3631 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3632 "expected 3-bit unsigned immediate");
3634 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3635 "expected 4-bit unsigned immediate");
3637 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3638 "expected 5-bit unsigned immediate");
3639 case Match_UImm5_32:
3640 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3641 "expected immediate in range 32 .. 63");
3642 case Match_UImm5_0_Report_UImm6:
3643 // This is used on UImm5 operands that have a corresponding UImm5_32
3644 // operand to avoid confusing the user.
3645 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3646 "expected 6-bit unsigned immediate");
3647 case Match_UImm5_Lsl2:
3648 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3649 "expected both 7-bit unsigned immediate and multiple of 4");
3651 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3652 "expected 6-bit unsigned immediate");
3654 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3655 "expected 6-bit signed immediate");
3657 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3658 "expected 7-bit unsigned immediate");
3660 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3661 "expected 8-bit unsigned immediate");
3662 case Match_UImm10_0:
3663 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3664 "expected 10-bit unsigned immediate");
3667 llvm_unreachable("Implement any new match types added!");
3670 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3671 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3672 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3673 ") without \".set noat\"");
3676 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3677 if (!AssemblerOptions.back()->isMacro())
3678 Warning(Loc, "macro instruction expanded into multiple instructions");
3682 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3683 SMRange Range, bool ShowColors) {
3684 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3685 Range, SMFixIt(Range, FixMsg),
3689 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3692 CC = StringSwitch<unsigned>(Name)
3728 if (!(isABI_N32() || isABI_N64()))
3731 if (12 <= CC && CC <= 15) {
3732 // Name is one of t4-t7
3733 AsmToken RegTok = getLexer().peekTok();
3734 SMRange RegRange = RegTok.getLocRange();
3736 StringRef FixedName = StringSwitch<StringRef>(Name)
3742 assert(FixedName != "" && "Register name is not one of t4-t7.");
3744 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3745 "Did you mean $" + FixedName + "?", RegRange);
3748 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3749 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3750 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3751 if (8 <= CC && CC <= 11)
3755 CC = StringSwitch<unsigned>(Name)
3767 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3770 CC = StringSwitch<unsigned>(Name)
3771 .Case("hwr_cpunum", 0)
3772 .Case("hwr_synci_step", 1)
3774 .Case("hwr_ccres", 3)
3775 .Case("hwr_ulr", 29)
3781 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3783 if (Name[0] == 'f') {
3784 StringRef NumString = Name.substr(1);
3786 if (NumString.getAsInteger(10, IntVal))
3787 return -1; // This is not an integer.
3788 if (IntVal > 31) // Maximum index for fpu register.
3795 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3797 if (Name.startswith("fcc")) {
3798 StringRef NumString = Name.substr(3);
3800 if (NumString.getAsInteger(10, IntVal))
3801 return -1; // This is not an integer.
3802 if (IntVal > 7) // There are only 8 fcc registers.
3809 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3811 if (Name.startswith("ac")) {
3812 StringRef NumString = Name.substr(2);
3814 if (NumString.getAsInteger(10, IntVal))
3815 return -1; // This is not an integer.
3816 if (IntVal > 3) // There are only 3 acc registers.
3823 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3826 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3835 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3838 CC = StringSwitch<unsigned>(Name)
3841 .Case("msaaccess", 2)
3843 .Case("msamodify", 4)
3844 .Case("msarequest", 5)
3846 .Case("msaunmap", 7)
3852 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3853 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3855 reportParseError(Loc,
3856 "pseudo-instruction requires $at, which is not available");
3859 unsigned AT = getReg(
3860 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3864 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3865 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3868 unsigned MipsAsmParser::getGPR(int RegNo) {
3869 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3873 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3875 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3878 return getReg(RegClass, RegNum);
3881 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3882 MCAsmParser &Parser = getParser();
3883 DEBUG(dbgs() << "parseOperand\n");
3885 // Check if the current operand has a custom associated parser, if so, try to
3886 // custom parse the operand, or fallback to the general approach.
3887 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3888 if (ResTy == MatchOperand_Success)
3890 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3891 // there was a match, but an error occurred, in which case, just return that
3892 // the operand parsing failed.
3893 if (ResTy == MatchOperand_ParseFail)
3896 DEBUG(dbgs() << ".. Generic Parser\n");
3898 switch (getLexer().getKind()) {
3900 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3902 case AsmToken::Dollar: {
3903 // Parse the register.
3904 SMLoc S = Parser.getTok().getLoc();
3906 // Almost all registers have been parsed by custom parsers. There is only
3907 // one exception to this. $zero (and it's alias $0) will reach this point
3908 // for div, divu, and similar instructions because it is not an operand
3909 // to the instruction definition but an explicit register. Special case
3910 // this situation for now.
3911 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3914 // Maybe it is a symbol reference.
3915 StringRef Identifier;
3916 if (Parser.parseIdentifier(Identifier))
3919 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3920 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3921 // Otherwise create a symbol reference.
3923 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3925 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3928 // Else drop to expression parsing.
3929 case AsmToken::LParen:
3930 case AsmToken::Minus:
3931 case AsmToken::Plus:
3932 case AsmToken::Integer:
3933 case AsmToken::Tilde:
3934 case AsmToken::String: {
3935 DEBUG(dbgs() << ".. generic integer\n");
3936 OperandMatchResultTy ResTy = parseImm(Operands);
3937 return ResTy != MatchOperand_Success;
3939 case AsmToken::Percent: {
3940 // It is a symbol reference or constant expression.
3941 const MCExpr *IdVal;
3942 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3943 if (parseRelocOperand(IdVal))
3946 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3948 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3950 } // case AsmToken::Percent
3951 } // switch(getLexer().getKind())
3955 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3956 StringRef RelocStr) {
3958 // Check the type of the expression.
3959 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3960 // It's a constant, evaluate reloc value.
3962 switch (getVariantKind(RelocStr)) {
3963 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3964 // Get the 1st 16-bits.
3965 Val = MCE->getValue() & 0xffff;
3967 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3968 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3969 // 16 bits being negative.
3970 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3972 case MCSymbolRefExpr::VK_Mips_HIGHER:
3973 // Get the 3rd 16-bits.
3974 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3976 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3977 // Get the 4th 16-bits.
3978 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3981 report_fatal_error("unsupported reloc value");
3983 return MCConstantExpr::create(Val, getContext());
3986 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3987 // It's a symbol, create a symbolic expression from the symbol.
3988 const MCSymbol *Symbol = &MSRE->getSymbol();
3989 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3990 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3994 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3995 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3997 // Try to create target expression.
3998 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3999 return MipsMCExpr::create(VK, Expr, getContext());
4001 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
4002 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
4003 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
4007 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
4008 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
4009 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
4012 // Just return the original expression.
4016 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
4018 switch (Expr->getKind()) {
4019 case MCExpr::Constant:
4021 case MCExpr::SymbolRef:
4022 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
4023 case MCExpr::Binary:
4024 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4025 if (!isEvaluated(BE->getLHS()))
4027 return isEvaluated(BE->getRHS());
4030 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
4031 case MCExpr::Target:
4037 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
4038 MCAsmParser &Parser = getParser();
4039 Parser.Lex(); // Eat the % token.
4040 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
4041 if (Tok.isNot(AsmToken::Identifier))
4044 std::string Str = Tok.getIdentifier();
4046 Parser.Lex(); // Eat the identifier.
4047 // Now make an expression from the rest of the operand.
4048 const MCExpr *IdVal;
4051 if (getLexer().getKind() == AsmToken::LParen) {
4053 Parser.Lex(); // Eat the '(' token.
4054 if (getLexer().getKind() == AsmToken::Percent) {
4055 Parser.Lex(); // Eat the % token.
4056 const AsmToken &nextTok = Parser.getTok();
4057 if (nextTok.isNot(AsmToken::Identifier))
4060 Str += nextTok.getIdentifier();
4061 Parser.Lex(); // Eat the identifier.
4062 if (getLexer().getKind() != AsmToken::LParen)
4067 if (getParser().parseParenExpression(IdVal, EndLoc))
4070 while (getLexer().getKind() == AsmToken::RParen)
4071 Parser.Lex(); // Eat the ')' token.
4074 return true; // Parenthesis must follow the relocation operand.
4076 Res = evaluateRelocExpr(IdVal, Str);
4080 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
4082 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
4083 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4084 if (ResTy == MatchOperand_Success) {
4085 assert(Operands.size() == 1);
4086 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
4087 StartLoc = Operand.getStartLoc();
4088 EndLoc = Operand.getEndLoc();
4090 // AFAIK, we only support numeric registers and named GPR's in CFI
4092 // Don't worry about eating tokens before failing. Using an unrecognised
4093 // register is a parse error.
4094 if (Operand.isGPRAsmReg()) {
4095 // Resolve to GPR32 or GPR64 appropriately.
4096 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
4099 return (RegNo == (unsigned)-1);
4102 assert(Operands.size() == 0);
4103 return (RegNo == (unsigned)-1);
4106 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
4107 MCAsmParser &Parser = getParser();
4110 unsigned NumOfLParen = 0;
4112 while (getLexer().getKind() == AsmToken::LParen) {
4117 switch (getLexer().getKind()) {
4120 case AsmToken::Identifier:
4121 case AsmToken::LParen:
4122 case AsmToken::Integer:
4123 case AsmToken::Minus:
4124 case AsmToken::Plus:
4126 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
4128 Result = (getParser().parseExpression(Res));
4129 while (getLexer().getKind() == AsmToken::RParen)
4132 case AsmToken::Percent:
4133 Result = parseRelocOperand(Res);
4138 MipsAsmParser::OperandMatchResultTy
4139 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
4140 MCAsmParser &Parser = getParser();
4141 DEBUG(dbgs() << "parseMemOperand\n");
4142 const MCExpr *IdVal = nullptr;
4144 bool isParenExpr = false;
4145 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
4146 // First operand is the offset.
4147 S = Parser.getTok().getLoc();
4149 if (getLexer().getKind() == AsmToken::LParen) {
4154 if (getLexer().getKind() != AsmToken::Dollar) {
4155 if (parseMemOffset(IdVal, isParenExpr))
4156 return MatchOperand_ParseFail;
4158 const AsmToken &Tok = Parser.getTok(); // Get the next token.
4159 if (Tok.isNot(AsmToken::LParen)) {
4160 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
4161 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
4163 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4164 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4165 return MatchOperand_Success;
4167 if (Tok.is(AsmToken::EndOfStatement)) {
4169 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4171 // Zero register assumed, add a memory operand with ZERO as its base.
4172 // "Base" will be managed by k_Memory.
4173 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
4176 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
4177 return MatchOperand_Success;
4179 Error(Parser.getTok().getLoc(), "'(' expected");
4180 return MatchOperand_ParseFail;
4183 Parser.Lex(); // Eat the '(' token.
4186 Res = parseAnyRegister(Operands);
4187 if (Res != MatchOperand_Success)
4190 if (Parser.getTok().isNot(AsmToken::RParen)) {
4191 Error(Parser.getTok().getLoc(), "')' expected");
4192 return MatchOperand_ParseFail;
4195 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4197 Parser.Lex(); // Eat the ')' token.
4200 IdVal = MCConstantExpr::create(0, getContext());
4202 // Replace the register operand with the memory operand.
4203 std::unique_ptr<MipsOperand> op(
4204 static_cast<MipsOperand *>(Operands.back().release()));
4205 // Remove the register from the operands.
4206 // "op" will be managed by k_Memory.
4207 Operands.pop_back();
4208 // Add the memory operand.
4209 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
4211 if (IdVal->evaluateAsAbsolute(Imm))
4212 IdVal = MCConstantExpr::create(Imm, getContext());
4213 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
4214 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
4218 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
4219 return MatchOperand_Success;
4222 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
4223 MCAsmParser &Parser = getParser();
4224 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
4226 SMLoc S = Parser.getTok().getLoc();
4228 if (Sym->isVariable())
4229 Expr = Sym->getVariableValue();
4232 if (Expr->getKind() == MCExpr::SymbolRef) {
4233 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4234 StringRef DefSymbol = Ref->getSymbol().getName();
4235 if (DefSymbol.startswith("$")) {
4236 OperandMatchResultTy ResTy =
4237 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
4238 if (ResTy == MatchOperand_Success) {
4241 } else if (ResTy == MatchOperand_ParseFail)
4242 llvm_unreachable("Should never ParseFail");
4245 } else if (Expr->getKind() == MCExpr::Constant) {
4247 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
4249 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
4256 MipsAsmParser::OperandMatchResultTy
4257 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
4258 StringRef Identifier,
4260 int Index = matchCPURegisterName(Identifier);
4262 Operands.push_back(MipsOperand::createGPRReg(
4263 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4264 return MatchOperand_Success;
4267 Index = matchHWRegsRegisterName(Identifier);
4269 Operands.push_back(MipsOperand::createHWRegsReg(
4270 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4271 return MatchOperand_Success;
4274 Index = matchFPURegisterName(Identifier);
4276 Operands.push_back(MipsOperand::createFGRReg(
4277 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4278 return MatchOperand_Success;
4281 Index = matchFCCRegisterName(Identifier);
4283 Operands.push_back(MipsOperand::createFCCReg(
4284 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4285 return MatchOperand_Success;
4288 Index = matchACRegisterName(Identifier);
4290 Operands.push_back(MipsOperand::createACCReg(
4291 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4292 return MatchOperand_Success;
4295 Index = matchMSA128RegisterName(Identifier);
4297 Operands.push_back(MipsOperand::createMSA128Reg(
4298 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4299 return MatchOperand_Success;
4302 Index = matchMSA128CtrlRegisterName(Identifier);
4304 Operands.push_back(MipsOperand::createMSACtrlReg(
4305 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4306 return MatchOperand_Success;
4309 return MatchOperand_NoMatch;
4312 MipsAsmParser::OperandMatchResultTy
4313 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
4314 MCAsmParser &Parser = getParser();
4315 auto Token = Parser.getLexer().peekTok(false);
4317 if (Token.is(AsmToken::Identifier)) {
4318 DEBUG(dbgs() << ".. identifier\n");
4319 StringRef Identifier = Token.getIdentifier();
4320 OperandMatchResultTy ResTy =
4321 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4323 } else if (Token.is(AsmToken::Integer)) {
4324 DEBUG(dbgs() << ".. integer\n");
4325 Operands.push_back(MipsOperand::createNumericReg(
4326 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
4328 return MatchOperand_Success;
4331 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4333 return MatchOperand_NoMatch;
4336 MipsAsmParser::OperandMatchResultTy
4337 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4338 MCAsmParser &Parser = getParser();
4339 DEBUG(dbgs() << "parseAnyRegister\n");
4341 auto Token = Parser.getTok();
4343 SMLoc S = Token.getLoc();
4345 if (Token.isNot(AsmToken::Dollar)) {
4346 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4347 if (Token.is(AsmToken::Identifier)) {
4348 if (searchSymbolAlias(Operands))
4349 return MatchOperand_Success;
4351 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4352 return MatchOperand_NoMatch;
4354 DEBUG(dbgs() << ".. $\n");
4356 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4357 if (ResTy == MatchOperand_Success) {
4359 Parser.Lex(); // identifier
4364 MipsAsmParser::OperandMatchResultTy
4365 MipsAsmParser::parseImm(OperandVector &Operands) {
4366 MCAsmParser &Parser = getParser();
4367 switch (getLexer().getKind()) {
4369 return MatchOperand_NoMatch;
4370 case AsmToken::LParen:
4371 case AsmToken::Minus:
4372 case AsmToken::Plus:
4373 case AsmToken::Integer:
4374 case AsmToken::Tilde:
4375 case AsmToken::String:
4379 const MCExpr *IdVal;
4380 SMLoc S = Parser.getTok().getLoc();
4381 if (getParser().parseExpression(IdVal))
4382 return MatchOperand_ParseFail;
4384 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4385 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4386 return MatchOperand_Success;
4389 MipsAsmParser::OperandMatchResultTy
4390 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4391 MCAsmParser &Parser = getParser();
4392 DEBUG(dbgs() << "parseJumpTarget\n");
4394 SMLoc S = getLexer().getLoc();
4396 // Integers and expressions are acceptable
4397 OperandMatchResultTy ResTy = parseImm(Operands);
4398 if (ResTy != MatchOperand_NoMatch)
4401 // Registers are a valid target and have priority over symbols.
4402 ResTy = parseAnyRegister(Operands);
4403 if (ResTy != MatchOperand_NoMatch)
4406 const MCExpr *Expr = nullptr;
4407 if (Parser.parseExpression(Expr)) {
4408 // We have no way of knowing if a symbol was consumed so we must ParseFail
4409 return MatchOperand_ParseFail;
4412 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4413 return MatchOperand_Success;
4416 MipsAsmParser::OperandMatchResultTy
4417 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4418 MCAsmParser &Parser = getParser();
4419 const MCExpr *IdVal;
4420 // If the first token is '$' we may have register operand.
4421 if (Parser.getTok().is(AsmToken::Dollar))
4422 return MatchOperand_NoMatch;
4423 SMLoc S = Parser.getTok().getLoc();
4424 if (getParser().parseExpression(IdVal))
4425 return MatchOperand_ParseFail;
4426 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4427 assert(MCE && "Unexpected MCExpr type.");
4428 int64_t Val = MCE->getValue();
4429 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4430 Operands.push_back(MipsOperand::CreateImm(
4431 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4432 return MatchOperand_Success;
4435 MipsAsmParser::OperandMatchResultTy
4436 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4437 MCAsmParser &Parser = getParser();
4438 switch (getLexer().getKind()) {
4440 return MatchOperand_NoMatch;
4441 case AsmToken::LParen:
4442 case AsmToken::Plus:
4443 case AsmToken::Minus:
4444 case AsmToken::Integer:
4449 SMLoc S = Parser.getTok().getLoc();
4451 if (getParser().parseExpression(Expr))
4452 return MatchOperand_ParseFail;
4455 if (!Expr->evaluateAsAbsolute(Val)) {
4456 Error(S, "expected immediate value");
4457 return MatchOperand_ParseFail;
4460 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4461 // and because the CPU always adds one to the immediate field, the allowed
4462 // range becomes 1..4. We'll only check the range here and will deal
4463 // with the addition/subtraction when actually decoding/encoding
4465 if (Val < 1 || Val > 4) {
4466 Error(S, "immediate not in range (1..4)");
4467 return MatchOperand_ParseFail;
4471 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4472 return MatchOperand_Success;
4475 MipsAsmParser::OperandMatchResultTy
4476 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4477 MCAsmParser &Parser = getParser();
4478 SmallVector<unsigned, 10> Regs;
4480 unsigned PrevReg = Mips::NoRegister;
4481 bool RegRange = false;
4482 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4484 if (Parser.getTok().isNot(AsmToken::Dollar))
4485 return MatchOperand_ParseFail;
4487 SMLoc S = Parser.getTok().getLoc();
4488 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4489 SMLoc E = getLexer().getLoc();
4490 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4491 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4493 // Remove last register operand because registers from register range
4494 // should be inserted first.
4495 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4496 (!isGP64bit() && RegNo == Mips::RA)) {
4497 Regs.push_back(RegNo);
4499 unsigned TmpReg = PrevReg + 1;
4500 while (TmpReg <= RegNo) {
4501 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4502 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4504 Error(E, "invalid register operand");
4505 return MatchOperand_ParseFail;
4509 Regs.push_back(TmpReg++);
4515 if ((PrevReg == Mips::NoRegister) &&
4516 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
4517 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
4518 Error(E, "$16 or $31 expected");
4519 return MatchOperand_ParseFail;
4520 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
4521 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
4523 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
4524 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
4526 Error(E, "invalid register operand");
4527 return MatchOperand_ParseFail;
4528 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4529 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
4530 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
4532 Error(E, "consecutive register numbers expected");
4533 return MatchOperand_ParseFail;
4536 Regs.push_back(RegNo);
4539 if (Parser.getTok().is(AsmToken::Minus))
4542 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4543 !Parser.getTok().isNot(AsmToken::Comma)) {
4544 Error(E, "',' or '-' expected");
4545 return MatchOperand_ParseFail;
4548 Lex(); // Consume comma or minus
4549 if (Parser.getTok().isNot(AsmToken::Dollar))
4555 SMLoc E = Parser.getTok().getLoc();
4556 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4557 parseMemOperand(Operands);
4558 return MatchOperand_Success;
4561 MipsAsmParser::OperandMatchResultTy
4562 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4563 MCAsmParser &Parser = getParser();
4565 SMLoc S = Parser.getTok().getLoc();
4566 if (parseAnyRegister(Operands) != MatchOperand_Success)
4567 return MatchOperand_ParseFail;
4569 SMLoc E = Parser.getTok().getLoc();
4570 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4571 unsigned Reg = Op.getGPR32Reg();
4572 Operands.pop_back();
4573 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4574 return MatchOperand_Success;
4577 MipsAsmParser::OperandMatchResultTy
4578 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4579 MCAsmParser &Parser = getParser();
4580 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4581 SmallVector<unsigned, 10> Regs;
4583 if (Parser.getTok().isNot(AsmToken::Dollar))
4584 return MatchOperand_ParseFail;
4586 SMLoc S = Parser.getTok().getLoc();
4588 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4589 return MatchOperand_ParseFail;
4591 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4592 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4593 Regs.push_back(RegNo);
4595 SMLoc E = Parser.getTok().getLoc();
4596 if (Parser.getTok().isNot(AsmToken::Comma)) {
4597 Error(E, "',' expected");
4598 return MatchOperand_ParseFail;
4604 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4605 return MatchOperand_ParseFail;
4607 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4608 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4609 Regs.push_back(RegNo);
4611 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4613 return MatchOperand_Success;
4616 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4618 MCSymbolRefExpr::VariantKind VK =
4619 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4620 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4621 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4622 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4623 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4624 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4625 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4626 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4627 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4628 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4629 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4630 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4631 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4632 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4633 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4634 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4635 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4636 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4637 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4638 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4639 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4640 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4641 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4642 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4643 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4644 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4645 .Default(MCSymbolRefExpr::VK_None);
4647 assert(VK != MCSymbolRefExpr::VK_None);
4652 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4654 /// ::= '(', register, ')'
4655 /// handle it before we iterate so we don't get tripped up by the lack of
4657 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4658 MCAsmParser &Parser = getParser();
4659 if (getLexer().is(AsmToken::LParen)) {
4661 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4663 if (parseOperand(Operands, Name)) {
4664 SMLoc Loc = getLexer().getLoc();
4665 Parser.eatToEndOfStatement();
4666 return Error(Loc, "unexpected token in argument list");
4668 if (Parser.getTok().isNot(AsmToken::RParen)) {
4669 SMLoc Loc = getLexer().getLoc();
4670 Parser.eatToEndOfStatement();
4671 return Error(Loc, "unexpected token, expected ')'");
4674 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4680 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4681 /// either one of these.
4682 /// ::= '[', register, ']'
4683 /// ::= '[', integer, ']'
4684 /// handle it before we iterate so we don't get tripped up by the lack of
4686 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4687 OperandVector &Operands) {
4688 MCAsmParser &Parser = getParser();
4689 if (getLexer().is(AsmToken::LBrac)) {
4691 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4693 if (parseOperand(Operands, Name)) {
4694 SMLoc Loc = getLexer().getLoc();
4695 Parser.eatToEndOfStatement();
4696 return Error(Loc, "unexpected token in argument list");
4698 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4699 SMLoc Loc = getLexer().getLoc();
4700 Parser.eatToEndOfStatement();
4701 return Error(Loc, "unexpected token, expected ']'");
4704 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4710 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4711 SMLoc NameLoc, OperandVector &Operands) {
4712 MCAsmParser &Parser = getParser();
4713 DEBUG(dbgs() << "ParseInstruction\n");
4715 // We have reached first instruction, module directive are now forbidden.
4716 getTargetStreamer().forbidModuleDirective();
4718 // Check if we have valid mnemonic
4719 if (!mnemonicIsValid(Name, 0)) {
4720 Parser.eatToEndOfStatement();
4721 return Error(NameLoc, "unknown instruction");
4723 // First operand in MCInst is instruction mnemonic.
4724 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4726 // Read the remaining operands.
4727 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4728 // Read the first operand.
4729 if (parseOperand(Operands, Name)) {
4730 SMLoc Loc = getLexer().getLoc();
4731 Parser.eatToEndOfStatement();
4732 return Error(Loc, "unexpected token in argument list");
4734 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4736 // AFAIK, parenthesis suffixes are never on the first operand
4738 while (getLexer().is(AsmToken::Comma)) {
4739 Parser.Lex(); // Eat the comma.
4740 // Parse and remember the operand.
4741 if (parseOperand(Operands, Name)) {
4742 SMLoc Loc = getLexer().getLoc();
4743 Parser.eatToEndOfStatement();
4744 return Error(Loc, "unexpected token in argument list");
4746 // Parse bracket and parenthesis suffixes before we iterate
4747 if (getLexer().is(AsmToken::LBrac)) {
4748 if (parseBracketSuffix(Name, Operands))
4750 } else if (getLexer().is(AsmToken::LParen) &&
4751 parseParenSuffix(Name, Operands))
4755 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4756 SMLoc Loc = getLexer().getLoc();
4757 Parser.eatToEndOfStatement();
4758 return Error(Loc, "unexpected token in argument list");
4760 Parser.Lex(); // Consume the EndOfStatement.
4764 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4765 MCAsmParser &Parser = getParser();
4766 SMLoc Loc = getLexer().getLoc();
4767 Parser.eatToEndOfStatement();
4768 return Error(Loc, ErrorMsg);
4771 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4772 return Error(Loc, ErrorMsg);
4775 bool MipsAsmParser::parseSetNoAtDirective() {
4776 MCAsmParser &Parser = getParser();
4777 // Line should look like: ".set noat".
4779 // Set the $at register to $0.
4780 AssemblerOptions.back()->setATRegIndex(0);
4782 Parser.Lex(); // Eat "noat".
4784 // If this is not the end of the statement, report an error.
4785 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4786 reportParseError("unexpected token, expected end of statement");
4790 getTargetStreamer().emitDirectiveSetNoAt();
4791 Parser.Lex(); // Consume the EndOfStatement.
4795 bool MipsAsmParser::parseSetAtDirective() {
4796 // Line can be: ".set at", which sets $at to $1
4797 // or ".set at=$reg", which sets $at to $reg.
4798 MCAsmParser &Parser = getParser();
4799 Parser.Lex(); // Eat "at".
4801 if (getLexer().is(AsmToken::EndOfStatement)) {
4802 // No register was specified, so we set $at to $1.
4803 AssemblerOptions.back()->setATRegIndex(1);
4805 getTargetStreamer().emitDirectiveSetAt();
4806 Parser.Lex(); // Consume the EndOfStatement.
4810 if (getLexer().isNot(AsmToken::Equal)) {
4811 reportParseError("unexpected token, expected equals sign");
4814 Parser.Lex(); // Eat "=".
4816 if (getLexer().isNot(AsmToken::Dollar)) {
4817 if (getLexer().is(AsmToken::EndOfStatement)) {
4818 reportParseError("no register specified");
4821 reportParseError("unexpected token, expected dollar sign '$'");
4825 Parser.Lex(); // Eat "$".
4827 // Find out what "reg" is.
4829 const AsmToken &Reg = Parser.getTok();
4830 if (Reg.is(AsmToken::Identifier)) {
4831 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4832 } else if (Reg.is(AsmToken::Integer)) {
4833 AtRegNo = Reg.getIntVal();
4835 reportParseError("unexpected token, expected identifier or integer");
4839 // Check if $reg is a valid register. If it is, set $at to $reg.
4840 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4841 reportParseError("invalid register");
4844 Parser.Lex(); // Eat "reg".
4846 // If this is not the end of the statement, report an error.
4847 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4848 reportParseError("unexpected token, expected end of statement");
4852 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4854 Parser.Lex(); // Consume the EndOfStatement.
4858 bool MipsAsmParser::parseSetReorderDirective() {
4859 MCAsmParser &Parser = getParser();
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");
4866 AssemblerOptions.back()->setReorder();
4867 getTargetStreamer().emitDirectiveSetReorder();
4868 Parser.Lex(); // Consume the EndOfStatement.
4872 bool MipsAsmParser::parseSetNoReorderDirective() {
4873 MCAsmParser &Parser = getParser();
4875 // If this is not the end of the statement, report an error.
4876 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4877 reportParseError("unexpected token, expected end of statement");
4880 AssemblerOptions.back()->setNoReorder();
4881 getTargetStreamer().emitDirectiveSetNoReorder();
4882 Parser.Lex(); // Consume the EndOfStatement.
4886 bool MipsAsmParser::parseSetMacroDirective() {
4887 MCAsmParser &Parser = getParser();
4889 // If this is not the end of the statement, report an error.
4890 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4891 reportParseError("unexpected token, expected end of statement");
4894 AssemblerOptions.back()->setMacro();
4895 getTargetStreamer().emitDirectiveSetMacro();
4896 Parser.Lex(); // Consume the EndOfStatement.
4900 bool MipsAsmParser::parseSetNoMacroDirective() {
4901 MCAsmParser &Parser = getParser();
4903 // If this is not the end of the statement, report an error.
4904 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4905 reportParseError("unexpected token, expected end of statement");
4908 if (AssemblerOptions.back()->isReorder()) {
4909 reportParseError("`noreorder' must be set before `nomacro'");
4912 AssemblerOptions.back()->setNoMacro();
4913 getTargetStreamer().emitDirectiveSetNoMacro();
4914 Parser.Lex(); // Consume the EndOfStatement.
4918 bool MipsAsmParser::parseSetMsaDirective() {
4919 MCAsmParser &Parser = getParser();
4922 // If this is not the end of the statement, report an error.
4923 if (getLexer().isNot(AsmToken::EndOfStatement))
4924 return reportParseError("unexpected token, expected end of statement");
4926 setFeatureBits(Mips::FeatureMSA, "msa");
4927 getTargetStreamer().emitDirectiveSetMsa();
4931 bool MipsAsmParser::parseSetNoMsaDirective() {
4932 MCAsmParser &Parser = getParser();
4935 // If this is not the end of the statement, report an error.
4936 if (getLexer().isNot(AsmToken::EndOfStatement))
4937 return reportParseError("unexpected token, expected end of statement");
4939 clearFeatureBits(Mips::FeatureMSA, "msa");
4940 getTargetStreamer().emitDirectiveSetNoMsa();
4944 bool MipsAsmParser::parseSetNoDspDirective() {
4945 MCAsmParser &Parser = getParser();
4946 Parser.Lex(); // Eat "nodsp".
4948 // If this is not the end of the statement, report an error.
4949 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4950 reportParseError("unexpected token, expected end of statement");
4954 clearFeatureBits(Mips::FeatureDSP, "dsp");
4955 getTargetStreamer().emitDirectiveSetNoDsp();
4959 bool MipsAsmParser::parseSetMips16Directive() {
4960 MCAsmParser &Parser = getParser();
4961 Parser.Lex(); // Eat "mips16".
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 setFeatureBits(Mips::FeatureMips16, "mips16");
4970 getTargetStreamer().emitDirectiveSetMips16();
4971 Parser.Lex(); // Consume the EndOfStatement.
4975 bool MipsAsmParser::parseSetNoMips16Directive() {
4976 MCAsmParser &Parser = getParser();
4977 Parser.Lex(); // Eat "nomips16".
4979 // If this is not the end of the statement, report an error.
4980 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4981 reportParseError("unexpected token, expected end of statement");
4985 clearFeatureBits(Mips::FeatureMips16, "mips16");
4986 getTargetStreamer().emitDirectiveSetNoMips16();
4987 Parser.Lex(); // Consume the EndOfStatement.
4991 bool MipsAsmParser::parseSetFpDirective() {
4992 MCAsmParser &Parser = getParser();
4993 MipsABIFlagsSection::FpABIKind FpAbiVal;
4994 // Line can be: .set fp=32
4997 Parser.Lex(); // Eat fp token
4998 AsmToken Tok = Parser.getTok();
4999 if (Tok.isNot(AsmToken::Equal)) {
5000 reportParseError("unexpected token, expected equals sign '='");
5003 Parser.Lex(); // Eat '=' token.
5004 Tok = Parser.getTok();
5006 if (!parseFpABIValue(FpAbiVal, ".set"))
5009 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5010 reportParseError("unexpected token, expected end of statement");
5013 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5014 Parser.Lex(); // Consume the EndOfStatement.
5018 bool MipsAsmParser::parseSetOddSPRegDirective() {
5019 MCAsmParser &Parser = getParser();
5021 Parser.Lex(); // Eat "oddspreg".
5022 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5023 reportParseError("unexpected token, expected end of statement");
5027 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5028 getTargetStreamer().emitDirectiveSetOddSPReg();
5032 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5033 MCAsmParser &Parser = getParser();
5035 Parser.Lex(); // Eat "nooddspreg".
5036 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5037 reportParseError("unexpected token, expected end of statement");
5041 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5042 getTargetStreamer().emitDirectiveSetNoOddSPReg();
5046 bool MipsAsmParser::parseSetPopDirective() {
5047 MCAsmParser &Parser = getParser();
5048 SMLoc Loc = getLexer().getLoc();
5051 if (getLexer().isNot(AsmToken::EndOfStatement))
5052 return reportParseError("unexpected token, expected end of statement");
5054 // Always keep an element on the options "stack" to prevent the user
5055 // from changing the initial options. This is how we remember them.
5056 if (AssemblerOptions.size() == 2)
5057 return reportParseError(Loc, ".set pop with no .set push");
5059 MCSubtargetInfo &STI = copySTI();
5060 AssemblerOptions.pop_back();
5061 setAvailableFeatures(
5062 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5063 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
5065 getTargetStreamer().emitDirectiveSetPop();
5069 bool MipsAsmParser::parseSetPushDirective() {
5070 MCAsmParser &Parser = getParser();
5072 if (getLexer().isNot(AsmToken::EndOfStatement))
5073 return reportParseError("unexpected token, expected end of statement");
5075 // Create a copy of the current assembler options environment and push it.
5076 AssemblerOptions.push_back(
5077 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5079 getTargetStreamer().emitDirectiveSetPush();
5083 bool MipsAsmParser::parseSetSoftFloatDirective() {
5084 MCAsmParser &Parser = getParser();
5086 if (getLexer().isNot(AsmToken::EndOfStatement))
5087 return reportParseError("unexpected token, expected end of statement");
5089 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5090 getTargetStreamer().emitDirectiveSetSoftFloat();
5094 bool MipsAsmParser::parseSetHardFloatDirective() {
5095 MCAsmParser &Parser = getParser();
5097 if (getLexer().isNot(AsmToken::EndOfStatement))
5098 return reportParseError("unexpected token, expected end of statement");
5100 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5101 getTargetStreamer().emitDirectiveSetHardFloat();
5105 bool MipsAsmParser::parseSetAssignment() {
5107 const MCExpr *Value;
5108 MCAsmParser &Parser = getParser();
5110 if (Parser.parseIdentifier(Name))
5111 reportParseError("expected identifier after .set");
5113 if (getLexer().isNot(AsmToken::Comma))
5114 return reportParseError("unexpected token, expected comma");
5117 if (Parser.parseExpression(Value))
5118 return reportParseError("expected valid expression after comma");
5120 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5121 Sym->setVariableValue(Value);
5126 bool MipsAsmParser::parseSetMips0Directive() {
5127 MCAsmParser &Parser = getParser();
5129 if (getLexer().isNot(AsmToken::EndOfStatement))
5130 return reportParseError("unexpected token, expected end of statement");
5132 // Reset assembler options to their initial values.
5133 MCSubtargetInfo &STI = copySTI();
5134 setAvailableFeatures(
5135 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
5136 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
5137 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
5139 getTargetStreamer().emitDirectiveSetMips0();
5143 bool MipsAsmParser::parseSetArchDirective() {
5144 MCAsmParser &Parser = getParser();
5146 if (getLexer().isNot(AsmToken::Equal))
5147 return reportParseError("unexpected token, expected equals sign");
5151 if (Parser.parseIdentifier(Arch))
5152 return reportParseError("expected arch identifier");
5154 StringRef ArchFeatureName =
5155 StringSwitch<StringRef>(Arch)
5156 .Case("mips1", "mips1")
5157 .Case("mips2", "mips2")
5158 .Case("mips3", "mips3")
5159 .Case("mips4", "mips4")
5160 .Case("mips5", "mips5")
5161 .Case("mips32", "mips32")
5162 .Case("mips32r2", "mips32r2")
5163 .Case("mips32r3", "mips32r3")
5164 .Case("mips32r5", "mips32r5")
5165 .Case("mips32r6", "mips32r6")
5166 .Case("mips64", "mips64")
5167 .Case("mips64r2", "mips64r2")
5168 .Case("mips64r3", "mips64r3")
5169 .Case("mips64r5", "mips64r5")
5170 .Case("mips64r6", "mips64r6")
5171 .Case("cnmips", "cnmips")
5172 .Case("r4000", "mips3") // This is an implementation of Mips3.
5175 if (ArchFeatureName.empty())
5176 return reportParseError("unsupported architecture");
5178 selectArch(ArchFeatureName);
5179 getTargetStreamer().emitDirectiveSetArch(Arch);
5183 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
5184 MCAsmParser &Parser = getParser();
5186 if (getLexer().isNot(AsmToken::EndOfStatement))
5187 return reportParseError("unexpected token, expected end of statement");
5191 llvm_unreachable("Unimplemented feature");
5192 case Mips::FeatureDSP:
5193 setFeatureBits(Mips::FeatureDSP, "dsp");
5194 getTargetStreamer().emitDirectiveSetDsp();
5196 case Mips::FeatureMicroMips:
5197 getTargetStreamer().emitDirectiveSetMicroMips();
5199 case Mips::FeatureMips1:
5200 selectArch("mips1");
5201 getTargetStreamer().emitDirectiveSetMips1();
5203 case Mips::FeatureMips2:
5204 selectArch("mips2");
5205 getTargetStreamer().emitDirectiveSetMips2();
5207 case Mips::FeatureMips3:
5208 selectArch("mips3");
5209 getTargetStreamer().emitDirectiveSetMips3();
5211 case Mips::FeatureMips4:
5212 selectArch("mips4");
5213 getTargetStreamer().emitDirectiveSetMips4();
5215 case Mips::FeatureMips5:
5216 selectArch("mips5");
5217 getTargetStreamer().emitDirectiveSetMips5();
5219 case Mips::FeatureMips32:
5220 selectArch("mips32");
5221 getTargetStreamer().emitDirectiveSetMips32();
5223 case Mips::FeatureMips32r2:
5224 selectArch("mips32r2");
5225 getTargetStreamer().emitDirectiveSetMips32R2();
5227 case Mips::FeatureMips32r3:
5228 selectArch("mips32r3");
5229 getTargetStreamer().emitDirectiveSetMips32R3();
5231 case Mips::FeatureMips32r5:
5232 selectArch("mips32r5");
5233 getTargetStreamer().emitDirectiveSetMips32R5();
5235 case Mips::FeatureMips32r6:
5236 selectArch("mips32r6");
5237 getTargetStreamer().emitDirectiveSetMips32R6();
5239 case Mips::FeatureMips64:
5240 selectArch("mips64");
5241 getTargetStreamer().emitDirectiveSetMips64();
5243 case Mips::FeatureMips64r2:
5244 selectArch("mips64r2");
5245 getTargetStreamer().emitDirectiveSetMips64R2();
5247 case Mips::FeatureMips64r3:
5248 selectArch("mips64r3");
5249 getTargetStreamer().emitDirectiveSetMips64R3();
5251 case Mips::FeatureMips64r5:
5252 selectArch("mips64r5");
5253 getTargetStreamer().emitDirectiveSetMips64R5();
5255 case Mips::FeatureMips64r6:
5256 selectArch("mips64r6");
5257 getTargetStreamer().emitDirectiveSetMips64R6();
5263 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
5264 MCAsmParser &Parser = getParser();
5265 if (getLexer().isNot(AsmToken::Comma)) {
5266 SMLoc Loc = getLexer().getLoc();
5267 Parser.eatToEndOfStatement();
5268 return Error(Loc, ErrorStr);
5271 Parser.Lex(); // Eat the comma.
5275 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
5276 // In this class, it is only used for .cprestore.
5277 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
5278 // MipsTargetELFStreamer and MipsAsmParser.
5279 bool MipsAsmParser::isPicAndNotNxxAbi() {
5280 return inPicMode() && !(isABI_N32() || isABI_N64());
5283 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
5284 if (AssemblerOptions.back()->isReorder())
5285 Warning(Loc, ".cpload should be inside a noreorder section");
5287 if (inMips16Mode()) {
5288 reportParseError(".cpload is not supported in Mips16 mode");
5292 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
5293 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
5294 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5295 reportParseError("expected register containing function address");
5299 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
5300 if (!RegOpnd.isGPRAsmReg()) {
5301 reportParseError(RegOpnd.getStartLoc(), "invalid register");
5305 // If this is not the end of the statement, report an error.
5306 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5307 reportParseError("unexpected token, expected end of statement");
5311 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5315 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5316 MCAsmParser &Parser = getParser();
5318 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5319 // is used in non-PIC mode.
5321 if (inMips16Mode()) {
5322 reportParseError(".cprestore is not supported in Mips16 mode");
5326 // Get the stack offset value.
5327 const MCExpr *StackOffset;
5328 int64_t StackOffsetVal;
5329 if (Parser.parseExpression(StackOffset)) {
5330 reportParseError("expected stack offset value");
5334 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5335 reportParseError("stack offset is not an absolute expression");
5339 if (StackOffsetVal < 0) {
5340 Warning(Loc, ".cprestore with negative stack offset has no effect");
5341 IsCpRestoreSet = false;
5343 IsCpRestoreSet = true;
5344 CpRestoreOffset = StackOffsetVal;
5347 // If this is not the end of the statement, report an error.
5348 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5349 reportParseError("unexpected token, expected end of statement");
5353 // Store the $gp on the stack.
5354 SmallVector<MCInst, 3> StoreInsts;
5355 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5358 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
5359 Parser.Lex(); // Consume the EndOfStatement.
5363 bool MipsAsmParser::parseDirectiveCPSetup() {
5364 MCAsmParser &Parser = getParser();
5367 bool SaveIsReg = true;
5369 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5370 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5371 if (ResTy == MatchOperand_NoMatch) {
5372 reportParseError("expected register containing function address");
5373 Parser.eatToEndOfStatement();
5377 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5378 if (!FuncRegOpnd.isGPRAsmReg()) {
5379 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5380 Parser.eatToEndOfStatement();
5384 FuncReg = FuncRegOpnd.getGPR32Reg();
5387 if (!eatComma("unexpected token, expected comma"))
5390 ResTy = parseAnyRegister(TmpReg);
5391 if (ResTy == MatchOperand_NoMatch) {
5392 const MCExpr *OffsetExpr;
5394 SMLoc ExprLoc = getLexer().getLoc();
5396 if (Parser.parseExpression(OffsetExpr) ||
5397 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5398 reportParseError(ExprLoc, "expected save register or stack offset");
5399 Parser.eatToEndOfStatement();
5406 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5407 if (!SaveOpnd.isGPRAsmReg()) {
5408 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5409 Parser.eatToEndOfStatement();
5412 Save = SaveOpnd.getGPR32Reg();
5415 if (!eatComma("unexpected token, expected comma"))
5419 if (Parser.parseExpression(Expr)) {
5420 reportParseError("expected expression");
5424 if (Expr->getKind() != MCExpr::SymbolRef) {
5425 reportParseError("expected symbol");
5428 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5430 CpSaveLocation = Save;
5431 CpSaveLocationIsRegister = SaveIsReg;
5433 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5438 bool MipsAsmParser::parseDirectiveCPReturn() {
5439 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5440 CpSaveLocationIsRegister);
5444 bool MipsAsmParser::parseDirectiveNaN() {
5445 MCAsmParser &Parser = getParser();
5446 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5447 const AsmToken &Tok = Parser.getTok();
5449 if (Tok.getString() == "2008") {
5451 getTargetStreamer().emitDirectiveNaN2008();
5453 } else if (Tok.getString() == "legacy") {
5455 getTargetStreamer().emitDirectiveNaNLegacy();
5459 // If we don't recognize the option passed to the .nan
5460 // directive (e.g. no option or unknown option), emit an error.
5461 reportParseError("invalid option in .nan directive");
5465 bool MipsAsmParser::parseDirectiveSet() {
5466 MCAsmParser &Parser = getParser();
5467 // Get the next token.
5468 const AsmToken &Tok = Parser.getTok();
5470 if (Tok.getString() == "noat") {
5471 return parseSetNoAtDirective();
5472 } else if (Tok.getString() == "at") {
5473 return parseSetAtDirective();
5474 } else if (Tok.getString() == "arch") {
5475 return parseSetArchDirective();
5476 } else if (Tok.getString() == "fp") {
5477 return parseSetFpDirective();
5478 } else if (Tok.getString() == "oddspreg") {
5479 return parseSetOddSPRegDirective();
5480 } else if (Tok.getString() == "nooddspreg") {
5481 return parseSetNoOddSPRegDirective();
5482 } else if (Tok.getString() == "pop") {
5483 return parseSetPopDirective();
5484 } else if (Tok.getString() == "push") {
5485 return parseSetPushDirective();
5486 } else if (Tok.getString() == "reorder") {
5487 return parseSetReorderDirective();
5488 } else if (Tok.getString() == "noreorder") {
5489 return parseSetNoReorderDirective();
5490 } else if (Tok.getString() == "macro") {
5491 return parseSetMacroDirective();
5492 } else if (Tok.getString() == "nomacro") {
5493 return parseSetNoMacroDirective();
5494 } else if (Tok.getString() == "mips16") {
5495 return parseSetMips16Directive();
5496 } else if (Tok.getString() == "nomips16") {
5497 return parseSetNoMips16Directive();
5498 } else if (Tok.getString() == "nomicromips") {
5499 getTargetStreamer().emitDirectiveSetNoMicroMips();
5500 Parser.eatToEndOfStatement();
5502 } else if (Tok.getString() == "micromips") {
5503 return parseSetFeature(Mips::FeatureMicroMips);
5504 } else if (Tok.getString() == "mips0") {
5505 return parseSetMips0Directive();
5506 } else if (Tok.getString() == "mips1") {
5507 return parseSetFeature(Mips::FeatureMips1);
5508 } else if (Tok.getString() == "mips2") {
5509 return parseSetFeature(Mips::FeatureMips2);
5510 } else if (Tok.getString() == "mips3") {
5511 return parseSetFeature(Mips::FeatureMips3);
5512 } else if (Tok.getString() == "mips4") {
5513 return parseSetFeature(Mips::FeatureMips4);
5514 } else if (Tok.getString() == "mips5") {
5515 return parseSetFeature(Mips::FeatureMips5);
5516 } else if (Tok.getString() == "mips32") {
5517 return parseSetFeature(Mips::FeatureMips32);
5518 } else if (Tok.getString() == "mips32r2") {
5519 return parseSetFeature(Mips::FeatureMips32r2);
5520 } else if (Tok.getString() == "mips32r3") {
5521 return parseSetFeature(Mips::FeatureMips32r3);
5522 } else if (Tok.getString() == "mips32r5") {
5523 return parseSetFeature(Mips::FeatureMips32r5);
5524 } else if (Tok.getString() == "mips32r6") {
5525 return parseSetFeature(Mips::FeatureMips32r6);
5526 } else if (Tok.getString() == "mips64") {
5527 return parseSetFeature(Mips::FeatureMips64);
5528 } else if (Tok.getString() == "mips64r2") {
5529 return parseSetFeature(Mips::FeatureMips64r2);
5530 } else if (Tok.getString() == "mips64r3") {
5531 return parseSetFeature(Mips::FeatureMips64r3);
5532 } else if (Tok.getString() == "mips64r5") {
5533 return parseSetFeature(Mips::FeatureMips64r5);
5534 } else if (Tok.getString() == "mips64r6") {
5535 return parseSetFeature(Mips::FeatureMips64r6);
5536 } else if (Tok.getString() == "dsp") {
5537 return parseSetFeature(Mips::FeatureDSP);
5538 } else if (Tok.getString() == "nodsp") {
5539 return parseSetNoDspDirective();
5540 } else if (Tok.getString() == "msa") {
5541 return parseSetMsaDirective();
5542 } else if (Tok.getString() == "nomsa") {
5543 return parseSetNoMsaDirective();
5544 } else if (Tok.getString() == "softfloat") {
5545 return parseSetSoftFloatDirective();
5546 } else if (Tok.getString() == "hardfloat") {
5547 return parseSetHardFloatDirective();
5549 // It is just an identifier, look for an assignment.
5550 parseSetAssignment();
5557 /// parseDataDirective
5558 /// ::= .word [ expression (, expression)* ]
5559 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5560 MCAsmParser &Parser = getParser();
5561 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5563 const MCExpr *Value;
5564 if (getParser().parseExpression(Value))
5567 getParser().getStreamer().EmitValue(Value, Size);
5569 if (getLexer().is(AsmToken::EndOfStatement))
5572 if (getLexer().isNot(AsmToken::Comma))
5573 return Error(L, "unexpected token, expected comma");
5582 /// parseDirectiveGpWord
5583 /// ::= .gpword local_sym
5584 bool MipsAsmParser::parseDirectiveGpWord() {
5585 MCAsmParser &Parser = getParser();
5586 const MCExpr *Value;
5587 // EmitGPRel32Value requires an expression, so we are using base class
5588 // method to evaluate the expression.
5589 if (getParser().parseExpression(Value))
5591 getParser().getStreamer().EmitGPRel32Value(Value);
5593 if (getLexer().isNot(AsmToken::EndOfStatement))
5594 return Error(getLexer().getLoc(),
5595 "unexpected token, expected end of statement");
5596 Parser.Lex(); // Eat EndOfStatement token.
5600 /// parseDirectiveGpDWord
5601 /// ::= .gpdword local_sym
5602 bool MipsAsmParser::parseDirectiveGpDWord() {
5603 MCAsmParser &Parser = getParser();
5604 const MCExpr *Value;
5605 // EmitGPRel64Value requires an expression, so we are using base class
5606 // method to evaluate the expression.
5607 if (getParser().parseExpression(Value))
5609 getParser().getStreamer().EmitGPRel64Value(Value);
5611 if (getLexer().isNot(AsmToken::EndOfStatement))
5612 return Error(getLexer().getLoc(),
5613 "unexpected token, expected end of statement");
5614 Parser.Lex(); // Eat EndOfStatement token.
5618 bool MipsAsmParser::parseDirectiveOption() {
5619 MCAsmParser &Parser = getParser();
5620 // Get the option token.
5621 AsmToken Tok = Parser.getTok();
5622 // At the moment only identifiers are supported.
5623 if (Tok.isNot(AsmToken::Identifier)) {
5624 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5625 Parser.eatToEndOfStatement();
5629 StringRef Option = Tok.getIdentifier();
5631 if (Option == "pic0") {
5632 // MipsAsmParser needs to know if the current PIC mode changes.
5633 IsPicEnabled = false;
5635 getTargetStreamer().emitDirectiveOptionPic0();
5637 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5638 Error(Parser.getTok().getLoc(),
5639 "unexpected token, expected end of statement");
5640 Parser.eatToEndOfStatement();
5645 if (Option == "pic2") {
5646 // MipsAsmParser needs to know if the current PIC mode changes.
5647 IsPicEnabled = true;
5649 getTargetStreamer().emitDirectiveOptionPic2();
5651 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5652 Error(Parser.getTok().getLoc(),
5653 "unexpected token, expected end of statement");
5654 Parser.eatToEndOfStatement();
5660 Warning(Parser.getTok().getLoc(),
5661 "unknown option, expected 'pic0' or 'pic2'");
5662 Parser.eatToEndOfStatement();
5666 /// parseInsnDirective
5668 bool MipsAsmParser::parseInsnDirective() {
5669 // If this is not the end of the statement, report an error.
5670 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5671 reportParseError("unexpected token, expected end of statement");
5675 // The actual label marking happens in
5676 // MipsELFStreamer::createPendingLabelRelocs().
5677 getTargetStreamer().emitDirectiveInsn();
5679 getParser().Lex(); // Eat EndOfStatement token.
5683 /// parseDirectiveModule
5684 /// ::= .module oddspreg
5685 /// ::= .module nooddspreg
5686 /// ::= .module fp=value
5687 /// ::= .module softfloat
5688 /// ::= .module hardfloat
5689 bool MipsAsmParser::parseDirectiveModule() {
5690 MCAsmParser &Parser = getParser();
5691 MCAsmLexer &Lexer = getLexer();
5692 SMLoc L = Lexer.getLoc();
5694 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5695 // TODO : get a better message.
5696 reportParseError(".module directive must appear before any code");
5701 if (Parser.parseIdentifier(Option)) {
5702 reportParseError("expected .module option identifier");
5706 if (Option == "oddspreg") {
5707 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5709 // Synchronize the abiflags information with the FeatureBits information we
5711 getTargetStreamer().updateABIInfo(*this);
5713 // If printing assembly, use the recently updated abiflags information.
5714 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5715 // emitted at the end).
5716 getTargetStreamer().emitDirectiveModuleOddSPReg();
5718 // If this is not the end of the statement, report an error.
5719 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5720 reportParseError("unexpected token, expected end of statement");
5724 return false; // parseDirectiveModule has finished successfully.
5725 } else if (Option == "nooddspreg") {
5727 Error(L, "'.module nooddspreg' requires the O32 ABI");
5731 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5733 // Synchronize the abiflags information with the FeatureBits information we
5735 getTargetStreamer().updateABIInfo(*this);
5737 // If printing assembly, use the recently updated abiflags information.
5738 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5739 // emitted at the end).
5740 getTargetStreamer().emitDirectiveModuleOddSPReg();
5742 // If this is not the end of the statement, report an error.
5743 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5744 reportParseError("unexpected token, expected end of statement");
5748 return false; // parseDirectiveModule has finished successfully.
5749 } else if (Option == "fp") {
5750 return parseDirectiveModuleFP();
5751 } else if (Option == "softfloat") {
5752 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5754 // Synchronize the ABI Flags information with the FeatureBits information we
5756 getTargetStreamer().updateABIInfo(*this);
5758 // If printing assembly, use the recently updated ABI Flags information.
5759 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5761 getTargetStreamer().emitDirectiveModuleSoftFloat();
5763 // If this is not the end of the statement, report an error.
5764 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5765 reportParseError("unexpected token, expected end of statement");
5769 return false; // parseDirectiveModule has finished successfully.
5770 } else if (Option == "hardfloat") {
5771 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5773 // Synchronize the ABI Flags information with the FeatureBits information we
5775 getTargetStreamer().updateABIInfo(*this);
5777 // If printing assembly, use the recently updated ABI Flags information.
5778 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5780 getTargetStreamer().emitDirectiveModuleHardFloat();
5782 // If this is not the end of the statement, report an error.
5783 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5784 reportParseError("unexpected token, expected end of statement");
5788 return false; // parseDirectiveModule has finished successfully.
5790 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5794 /// parseDirectiveModuleFP
5798 bool MipsAsmParser::parseDirectiveModuleFP() {
5799 MCAsmParser &Parser = getParser();
5800 MCAsmLexer &Lexer = getLexer();
5802 if (Lexer.isNot(AsmToken::Equal)) {
5803 reportParseError("unexpected token, expected equals sign '='");
5806 Parser.Lex(); // Eat '=' token.
5808 MipsABIFlagsSection::FpABIKind FpABI;
5809 if (!parseFpABIValue(FpABI, ".module"))
5812 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5813 reportParseError("unexpected token, expected end of statement");
5817 // Synchronize the abiflags information with the FeatureBits information we
5819 getTargetStreamer().updateABIInfo(*this);
5821 // If printing assembly, use the recently updated abiflags information.
5822 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5823 // emitted at the end).
5824 getTargetStreamer().emitDirectiveModuleFP();
5826 Parser.Lex(); // Consume the EndOfStatement.
5830 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5831 StringRef Directive) {
5832 MCAsmParser &Parser = getParser();
5833 MCAsmLexer &Lexer = getLexer();
5834 bool ModuleLevelOptions = Directive == ".module";
5836 if (Lexer.is(AsmToken::Identifier)) {
5837 StringRef Value = Parser.getTok().getString();
5840 if (Value != "xx") {
5841 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5846 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5850 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5851 if (ModuleLevelOptions) {
5852 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5853 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5855 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5856 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5861 if (Lexer.is(AsmToken::Integer)) {
5862 unsigned Value = Parser.getTok().getIntVal();
5865 if (Value != 32 && Value != 64) {
5866 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5872 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5876 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5877 if (ModuleLevelOptions) {
5878 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5879 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5881 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5882 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5885 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5886 if (ModuleLevelOptions) {
5887 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5888 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5890 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5891 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5901 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5902 MCAsmParser &Parser = getParser();
5903 StringRef IDVal = DirectiveID.getString();
5905 if (IDVal == ".cpload")
5906 return parseDirectiveCpLoad(DirectiveID.getLoc());
5907 if (IDVal == ".cprestore")
5908 return parseDirectiveCpRestore(DirectiveID.getLoc());
5909 if (IDVal == ".dword") {
5910 parseDataDirective(8, DirectiveID.getLoc());
5913 if (IDVal == ".ent") {
5914 StringRef SymbolName;
5916 if (Parser.parseIdentifier(SymbolName)) {
5917 reportParseError("expected identifier after .ent");
5921 // There's an undocumented extension that allows an integer to
5922 // follow the name of the procedure which AFAICS is ignored by GAS.
5923 // Example: .ent foo,2
5924 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5925 if (getLexer().isNot(AsmToken::Comma)) {
5926 // Even though we accept this undocumented extension for compatibility
5927 // reasons, the additional integer argument does not actually change
5928 // the behaviour of the '.ent' directive, so we would like to discourage
5929 // its use. We do this by not referring to the extended version in
5930 // error messages which are not directly related to its use.
5931 reportParseError("unexpected token, expected end of statement");
5934 Parser.Lex(); // Eat the comma.
5935 const MCExpr *DummyNumber;
5936 int64_t DummyNumberVal;
5937 // If the user was explicitly trying to use the extended version,
5938 // we still give helpful extension-related error messages.
5939 if (Parser.parseExpression(DummyNumber)) {
5940 reportParseError("expected number after comma");
5943 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5944 reportParseError("expected an absolute expression after comma");
5949 // If this is not the end of the statement, report an error.
5950 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5951 reportParseError("unexpected token, expected end of statement");
5955 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5957 getTargetStreamer().emitDirectiveEnt(*Sym);
5959 IsCpRestoreSet = false;
5963 if (IDVal == ".end") {
5964 StringRef SymbolName;
5966 if (Parser.parseIdentifier(SymbolName)) {
5967 reportParseError("expected identifier after .end");
5971 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5972 reportParseError("unexpected token, expected end of statement");
5976 if (CurrentFn == nullptr) {
5977 reportParseError(".end used without .ent");
5981 if ((SymbolName != CurrentFn->getName())) {
5982 reportParseError(".end symbol does not match .ent symbol");
5986 getTargetStreamer().emitDirectiveEnd(SymbolName);
5987 CurrentFn = nullptr;
5988 IsCpRestoreSet = false;
5992 if (IDVal == ".frame") {
5993 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5994 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5995 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5996 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5997 reportParseError("expected stack register");
6001 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6002 if (!StackRegOpnd.isGPRAsmReg()) {
6003 reportParseError(StackRegOpnd.getStartLoc(),
6004 "expected general purpose register");
6007 unsigned StackReg = StackRegOpnd.getGPR32Reg();
6009 if (Parser.getTok().is(AsmToken::Comma))
6012 reportParseError("unexpected token, expected comma");
6016 // Parse the frame size.
6017 const MCExpr *FrameSize;
6018 int64_t FrameSizeVal;
6020 if (Parser.parseExpression(FrameSize)) {
6021 reportParseError("expected frame size value");
6025 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
6026 reportParseError("frame size not an absolute expression");
6030 if (Parser.getTok().is(AsmToken::Comma))
6033 reportParseError("unexpected token, expected comma");
6037 // Parse the return register.
6039 ResTy = parseAnyRegister(TmpReg);
6040 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6041 reportParseError("expected return register");
6045 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6046 if (!ReturnRegOpnd.isGPRAsmReg()) {
6047 reportParseError(ReturnRegOpnd.getStartLoc(),
6048 "expected general purpose register");
6052 // If this is not the end of the statement, report an error.
6053 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6054 reportParseError("unexpected token, expected end of statement");
6058 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
6059 ReturnRegOpnd.getGPR32Reg());
6060 IsCpRestoreSet = false;
6064 if (IDVal == ".set") {
6065 return parseDirectiveSet();
6068 if (IDVal == ".mask" || IDVal == ".fmask") {
6069 // .mask bitmask, frame_offset
6070 // bitmask: One bit for each register used.
6071 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
6072 // first register is expected to be saved.
6074 // .mask 0x80000000, -4
6075 // .fmask 0x80000000, -4
6078 // Parse the bitmask
6079 const MCExpr *BitMask;
6082 if (Parser.parseExpression(BitMask)) {
6083 reportParseError("expected bitmask value");
6087 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
6088 reportParseError("bitmask not an absolute expression");
6092 if (Parser.getTok().is(AsmToken::Comma))
6095 reportParseError("unexpected token, expected comma");
6099 // Parse the frame_offset
6100 const MCExpr *FrameOffset;
6101 int64_t FrameOffsetVal;
6103 if (Parser.parseExpression(FrameOffset)) {
6104 reportParseError("expected frame offset value");
6108 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
6109 reportParseError("frame offset not an absolute expression");
6113 // If this is not the end of the statement, report an error.
6114 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6115 reportParseError("unexpected token, expected end of statement");
6119 if (IDVal == ".mask")
6120 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
6122 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6126 if (IDVal == ".nan")
6127 return parseDirectiveNaN();
6129 if (IDVal == ".gpword") {
6130 parseDirectiveGpWord();
6134 if (IDVal == ".gpdword") {
6135 parseDirectiveGpDWord();
6139 if (IDVal == ".word") {
6140 parseDataDirective(4, DirectiveID.getLoc());
6144 if (IDVal == ".option")
6145 return parseDirectiveOption();
6147 if (IDVal == ".abicalls") {
6148 getTargetStreamer().emitDirectiveAbiCalls();
6149 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6150 Error(Parser.getTok().getLoc(),
6151 "unexpected token, expected end of statement");
6153 Parser.eatToEndOfStatement();
6158 if (IDVal == ".cpsetup")
6159 return parseDirectiveCPSetup();
6161 if (IDVal == ".cpreturn")
6162 return parseDirectiveCPReturn();
6164 if (IDVal == ".module")
6165 return parseDirectiveModule();
6167 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
6168 return parseInternalDirectiveReallowModule();
6170 if (IDVal == ".insn")
6171 return parseInsnDirective();
6176 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
6177 // If this is not the end of the statement, report an error.
6178 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6179 reportParseError("unexpected token, expected end of statement");
6183 getTargetStreamer().reallowModuleDirective();
6185 getParser().Lex(); // Eat EndOfStatement token.
6189 extern "C" void LLVMInitializeMipsAsmParser() {
6190 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
6191 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
6192 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
6193 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
6196 #define GET_REGISTER_MATCHER
6197 #define GET_MATCHER_IMPLEMENTATION
6198 #include "MipsGenAsmMatcher.inc"