1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCParser/MCAsmLexer.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCTargetAsmParser.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
38 #define DEBUG_TYPE "mips-asm-parser"
45 class MipsAssemblerOptions {
47 MipsAssemblerOptions(const FeatureBitset &Features_) :
48 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
50 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
51 ATReg = Opts->getATRegIndex();
52 Reorder = Opts->isReorder();
53 Macro = Opts->isMacro();
54 Features = Opts->getFeatures();
57 unsigned getATRegIndex() const { return ATReg; }
58 bool setATRegIndex(unsigned Reg) {
66 bool isReorder() const { return Reorder; }
67 void setReorder() { Reorder = true; }
68 void setNoReorder() { Reorder = false; }
70 bool isMacro() const { return Macro; }
71 void setMacro() { Macro = true; }
72 void setNoMacro() { Macro = false; }
74 const FeatureBitset &getFeatures() const { return Features; }
75 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
77 // Set of features that are either architecture features or referenced
78 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
79 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
80 // The reason we need this mask is explained in the selectArch function.
81 // FIXME: Ideally we would like TableGen to generate this information.
82 static const FeatureBitset AllArchRelatedMask;
88 FeatureBitset Features;
92 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
93 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
94 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
95 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
96 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
97 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
98 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
99 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
100 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
104 class MipsAsmParser : public MCTargetAsmParser {
105 MipsTargetStreamer &getTargetStreamer() {
106 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
107 return static_cast<MipsTargetStreamer &>(TS);
110 MCSubtargetInfo &STI;
112 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
113 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
114 // nullptr, which indicates that no function is currently
115 // selected. This usually happens after an '.end func'
121 unsigned CpSaveLocation;
122 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
123 bool CpSaveLocationIsRegister;
125 // Print a warning along with its fix-it message at the given range.
126 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
127 SMRange Range, bool ShowColors = true);
129 #define GET_ASSEMBLER_HEADER
130 #include "MipsGenAsmMatcher.inc"
132 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
134 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
135 OperandVector &Operands, MCStreamer &Out,
137 bool MatchingInlineAsm) override;
139 /// Parse a register as used in CFI directives
140 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
142 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
144 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
146 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
147 SMLoc NameLoc, OperandVector &Operands) override;
149 bool ParseDirective(AsmToken DirectiveID) override;
151 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
153 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
154 StringRef Identifier, SMLoc S);
155 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
157 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
158 OperandMatchResultTy parseImm(OperandVector &Operands);
159 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
160 OperandMatchResultTy parseInvNum(OperandVector &Operands);
161 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
163 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
164 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
166 bool searchSymbolAlias(OperandVector &Operands);
168 bool parseOperand(OperandVector &, StringRef Mnemonic);
170 enum MacroExpanderResultTy {
176 // Expands assembly pseudo instructions.
177 MacroExpanderResultTy
178 tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
179 SmallVectorImpl<MCInst> &Instructions);
181 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
182 SmallVectorImpl<MCInst> &Instructions);
184 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
185 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
189 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
195 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
196 const MCOperand &Offset, bool Is32BitAddress,
197 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
199 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
200 SmallVectorImpl<MCInst> &Instructions);
202 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
206 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
207 SmallVectorImpl<MCInst> &Instructions);
209 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
210 SmallVectorImpl<MCInst> &Instructions);
212 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
213 SmallVectorImpl<MCInst> &Instructions);
215 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
216 SmallVectorImpl<MCInst> &Instructions);
218 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
222 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
223 SmallVectorImpl<MCInst> &Instructions);
225 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
226 SmallVectorImpl<MCInst> &Instructions);
228 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
229 SmallVectorImpl<MCInst> &Instructions);
231 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
232 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
234 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
235 SmallVectorImpl<MCInst> &Instructions);
237 bool reportParseError(Twine ErrorMsg);
238 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
240 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
241 bool parseRelocOperand(const MCExpr *&Res);
243 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
245 bool isEvaluated(const MCExpr *Expr);
246 bool parseSetMips0Directive();
247 bool parseSetArchDirective();
248 bool parseSetFeature(uint64_t Feature);
249 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
250 bool parseDirectiveCpLoad(SMLoc Loc);
251 bool parseDirectiveCpRestore(SMLoc Loc);
252 bool parseDirectiveCPSetup();
253 bool parseDirectiveCPReturn();
254 bool parseDirectiveNaN();
255 bool parseDirectiveSet();
256 bool parseDirectiveOption();
257 bool parseInsnDirective();
259 bool parseSetAtDirective();
260 bool parseSetNoAtDirective();
261 bool parseSetMacroDirective();
262 bool parseSetNoMacroDirective();
263 bool parseSetMsaDirective();
264 bool parseSetNoMsaDirective();
265 bool parseSetNoDspDirective();
266 bool parseSetReorderDirective();
267 bool parseSetNoReorderDirective();
268 bool parseSetMips16Directive();
269 bool parseSetNoMips16Directive();
270 bool parseSetFpDirective();
271 bool parseSetOddSPRegDirective();
272 bool parseSetNoOddSPRegDirective();
273 bool parseSetPopDirective();
274 bool parseSetPushDirective();
275 bool parseSetSoftFloatDirective();
276 bool parseSetHardFloatDirective();
278 bool parseSetAssignment();
280 bool parseDataDirective(unsigned Size, SMLoc L);
281 bool parseDirectiveGpWord();
282 bool parseDirectiveGpDWord();
283 bool parseDirectiveModule();
284 bool parseDirectiveModuleFP();
285 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
286 StringRef Directive);
288 bool parseInternalDirectiveReallowModule();
290 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
292 bool eatComma(StringRef ErrorStr);
294 int matchCPURegisterName(StringRef Symbol);
296 int matchHWRegsRegisterName(StringRef Symbol);
298 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
300 int matchFPURegisterName(StringRef Name);
302 int matchFCCRegisterName(StringRef Name);
304 int matchACRegisterName(StringRef Name);
306 int matchMSA128RegisterName(StringRef Name);
308 int matchMSA128CtrlRegisterName(StringRef Name);
310 unsigned getReg(int RC, int RegNo);
312 unsigned getGPR(int RegNo);
314 /// Returns the internal register number for the current AT. Also checks if
315 /// the current AT is unavailable (set to $0) and gives an error if it is.
316 /// This should be used in pseudo-instruction expansions which need AT.
317 unsigned getATReg(SMLoc Loc);
319 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
320 SmallVectorImpl<MCInst> &Instructions);
322 // Helper function that checks if the value of a vector index is within the
323 // boundaries of accepted values for each RegisterKind
324 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
325 bool validateMSAIndex(int Val, int RegKind);
327 // Selects a new architecture by updating the FeatureBits with the necessary
328 // info including implied dependencies.
329 // Internally, it clears all the feature bits related to *any* architecture
330 // and selects the new one using the ToggleFeature functionality of the
331 // MCSubtargetInfo object that handles implied dependencies. The reason we
332 // clear all the arch related bits manually is because ToggleFeature only
333 // clears the features that imply the feature being cleared and not the
334 // features implied by the feature being cleared. This is easier to see
336 // --------------------------------------------------
337 // | Feature | Implies |
338 // | -------------------------------------------------|
339 // | FeatureMips1 | None |
340 // | FeatureMips2 | FeatureMips1 |
341 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
342 // | FeatureMips4 | FeatureMips3 |
344 // --------------------------------------------------
346 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
347 // FeatureMipsGP64 | FeatureMips1)
348 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
349 void selectArch(StringRef ArchFeature) {
350 FeatureBitset FeatureBits = STI.getFeatureBits();
351 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
352 STI.setFeatureBits(FeatureBits);
353 setAvailableFeatures(
354 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
355 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
358 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
359 if (!(STI.getFeatureBits()[Feature])) {
360 setAvailableFeatures(
361 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
362 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
366 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
367 if (STI.getFeatureBits()[Feature]) {
368 setAvailableFeatures(
369 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
370 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
374 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
375 setFeatureBits(Feature, FeatureString);
376 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
379 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
380 clearFeatureBits(Feature, FeatureString);
381 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
385 enum MipsMatchResultTy {
386 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
387 #define GET_OPERAND_DIAGNOSTIC_TYPES
388 #include "MipsGenAsmMatcher.inc"
389 #undef GET_OPERAND_DIAGNOSTIC_TYPES
392 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
393 const MCInstrInfo &MII, const MCTargetOptions &Options)
394 : MCTargetAsmParser(Options), STI(sti),
395 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
396 sti.getCPU(), Options)) {
397 MCAsmParserExtension::Initialize(parser);
399 parser.addAliasForDirective(".asciiz", ".asciz");
401 // Initialize the set of available features.
402 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
404 // Remember the initial assembler options. The user can not modify these.
405 AssemblerOptions.push_back(
406 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
408 // Create an assembler options environment for the user to modify.
409 AssemblerOptions.push_back(
410 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
412 getTargetStreamer().updateABIInfo(*this);
414 if (!isABI_O32() && !useOddSPReg() != 0)
415 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
420 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
422 IsCpRestoreSet = false;
423 CpRestoreOffset = -1;
425 Triple TheTriple(sti.getTargetTriple());
426 if ((TheTriple.getArch() == Triple::mips) ||
427 (TheTriple.getArch() == Triple::mips64))
428 IsLittleEndian = false;
430 IsLittleEndian = true;
433 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
434 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
436 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
437 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
438 const MipsABIInfo &getABI() const { return ABI; }
439 bool isABI_N32() const { return ABI.IsN32(); }
440 bool isABI_N64() const { return ABI.IsN64(); }
441 bool isABI_O32() const { return ABI.IsO32(); }
442 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
444 bool useOddSPReg() const {
445 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
448 bool inMicroMipsMode() const {
449 return STI.getFeatureBits()[Mips::FeatureMicroMips];
451 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
452 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
453 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
454 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
455 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
456 bool hasMips32() const {
457 return STI.getFeatureBits()[Mips::FeatureMips32];
459 bool hasMips64() const {
460 return STI.getFeatureBits()[Mips::FeatureMips64];
462 bool hasMips32r2() const {
463 return STI.getFeatureBits()[Mips::FeatureMips32r2];
465 bool hasMips64r2() const {
466 return STI.getFeatureBits()[Mips::FeatureMips64r2];
468 bool hasMips32r3() const {
469 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
471 bool hasMips64r3() const {
472 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
474 bool hasMips32r5() const {
475 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
477 bool hasMips64r5() const {
478 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
480 bool hasMips32r6() const {
481 return STI.getFeatureBits()[Mips::FeatureMips32r6];
483 bool hasMips64r6() const {
484 return STI.getFeatureBits()[Mips::FeatureMips64r6];
487 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
488 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
489 bool hasDSPR3() const { return STI.getFeatureBits()[Mips::FeatureDSPR3]; }
490 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
491 bool hasCnMips() const {
492 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
499 bool inMips16Mode() const {
500 return STI.getFeatureBits()[Mips::FeatureMips16];
503 bool useTraps() const {
504 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
507 bool useSoftFloat() const {
508 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
511 /// Warn if RegIndex is the same as the current AT.
512 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
514 void warnIfNoMacro(SMLoc Loc);
516 bool isLittle() const { return IsLittleEndian; }
522 /// MipsOperand - Instances of this class represent a parsed Mips machine
524 class MipsOperand : public MCParsedAsmOperand {
526 /// Broad categories of register classes
527 /// The exact class is finalized by the render method.
529 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
530 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
532 RegKind_FCC = 4, /// FCC
533 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
534 RegKind_MSACtrl = 16, /// MSA control registers
535 RegKind_COP2 = 32, /// COP2
536 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
538 RegKind_CCR = 128, /// CCR
539 RegKind_HWRegs = 256, /// HWRegs
540 RegKind_COP3 = 512, /// COP3
541 RegKind_COP0 = 1024, /// COP0
542 /// Potentially any (e.g. $1)
543 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
544 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
545 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
550 k_Immediate, /// An immediate (possibly involving symbol references)
551 k_Memory, /// Base + Offset Memory Address
552 k_PhysRegister, /// A physical register from the Mips namespace
553 k_RegisterIndex, /// A register index in one or more RegKind.
554 k_Token, /// A simple token
555 k_RegList, /// A physical register list
556 k_RegPair /// A pair of physical register
560 MipsOperand(KindTy K, MipsAsmParser &Parser)
561 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
564 /// For diagnostics, and checking the assembler temporary
565 MipsAsmParser &AsmParser;
573 unsigned Num; /// Register Number
577 unsigned Index; /// Index into the register class
578 RegKind Kind; /// Bitfield of the kinds it could possibly be
579 const MCRegisterInfo *RegInfo;
592 SmallVector<unsigned, 10> *List;
597 struct PhysRegOp PhysReg;
598 struct RegIdxOp RegIdx;
601 struct RegListOp RegList;
604 SMLoc StartLoc, EndLoc;
606 /// Internal constructor for register kinds
607 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
608 const MCRegisterInfo *RegInfo,
610 MipsAsmParser &Parser) {
611 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
612 Op->RegIdx.Index = Index;
613 Op->RegIdx.RegInfo = RegInfo;
614 Op->RegIdx.Kind = RegKind;
621 /// Coerce the register to GPR32 and return the real register for the current
623 unsigned getGPR32Reg() const {
624 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
625 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
626 unsigned ClassID = Mips::GPR32RegClassID;
627 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
630 /// Coerce the register to GPR32 and return the real register for the current
632 unsigned getGPRMM16Reg() const {
633 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
634 unsigned ClassID = Mips::GPR32RegClassID;
635 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
638 /// Coerce the register to GPR64 and return the real register for the current
640 unsigned getGPR64Reg() const {
641 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
642 unsigned ClassID = Mips::GPR64RegClassID;
643 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
647 /// Coerce the register to AFGR64 and return the real register for the current
649 unsigned getAFGR64Reg() const {
650 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
651 if (RegIdx.Index % 2 != 0)
652 AsmParser.Warning(StartLoc, "Float register should be even.");
653 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
654 .getRegister(RegIdx.Index / 2);
657 /// Coerce the register to FGR64 and return the real register for the current
659 unsigned getFGR64Reg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
661 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
662 .getRegister(RegIdx.Index);
665 /// Coerce the register to FGR32 and return the real register for the current
667 unsigned getFGR32Reg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
669 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
670 .getRegister(RegIdx.Index);
673 /// Coerce the register to FGRH32 and return the real register for the current
675 unsigned getFGRH32Reg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
677 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
678 .getRegister(RegIdx.Index);
681 /// Coerce the register to FCC and return the real register for the current
683 unsigned getFCCReg() const {
684 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
685 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
686 .getRegister(RegIdx.Index);
689 /// Coerce the register to MSA128 and return the real register for the current
691 unsigned getMSA128Reg() const {
692 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
693 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
695 unsigned ClassID = Mips::MSA128BRegClassID;
696 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
699 /// Coerce the register to MSACtrl and return the real register for the
701 unsigned getMSACtrlReg() const {
702 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
703 unsigned ClassID = Mips::MSACtrlRegClassID;
704 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
707 /// Coerce the register to COP0 and return the real register for the
709 unsigned getCOP0Reg() const {
710 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
711 unsigned ClassID = Mips::COP0RegClassID;
712 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
715 /// Coerce the register to COP2 and return the real register for the
717 unsigned getCOP2Reg() const {
718 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
719 unsigned ClassID = Mips::COP2RegClassID;
720 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
723 /// Coerce the register to COP3 and return the real register for the
725 unsigned getCOP3Reg() const {
726 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
727 unsigned ClassID = Mips::COP3RegClassID;
728 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
731 /// Coerce the register to ACC64DSP and return the real register for the
733 unsigned getACC64DSPReg() const {
734 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
735 unsigned ClassID = Mips::ACC64DSPRegClassID;
736 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
739 /// Coerce the register to HI32DSP and return the real register for the
741 unsigned getHI32DSPReg() const {
742 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
743 unsigned ClassID = Mips::HI32DSPRegClassID;
744 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
747 /// Coerce the register to LO32DSP and return the real register for the
749 unsigned getLO32DSPReg() const {
750 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
751 unsigned ClassID = Mips::LO32DSPRegClassID;
752 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
755 /// Coerce the register to CCR and return the real register for the
757 unsigned getCCRReg() const {
758 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
759 unsigned ClassID = Mips::CCRRegClassID;
760 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
763 /// Coerce the register to HWRegs and return the real register for the
765 unsigned getHWRegsReg() const {
766 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
767 unsigned ClassID = Mips::HWRegsRegClassID;
768 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
772 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
773 // Add as immediate when possible. Null MCExpr = 0.
775 Inst.addOperand(MCOperand::createImm(0));
776 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
777 Inst.addOperand(MCOperand::createImm(CE->getValue()));
779 Inst.addOperand(MCOperand::createExpr(Expr));
782 void addRegOperands(MCInst &Inst, unsigned N) const {
783 llvm_unreachable("Use a custom parser instead");
786 /// Render the operand to an MCInst as a GPR32
787 /// Asserts if the wrong number of operands are requested, or the operand
788 /// is not a k_RegisterIndex compatible with RegKind_GPR
789 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
790 assert(N == 1 && "Invalid number of operands!");
791 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
794 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
795 assert(N == 1 && "Invalid number of operands!");
796 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
799 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
800 assert(N == 1 && "Invalid number of operands!");
801 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
804 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
805 assert(N == 1 && "Invalid number of operands!");
806 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
809 /// Render the operand to an MCInst as a GPR64
810 /// Asserts if the wrong number of operands are requested, or the operand
811 /// is not a k_RegisterIndex compatible with RegKind_GPR
812 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
813 assert(N == 1 && "Invalid number of operands!");
814 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
817 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
818 assert(N == 1 && "Invalid number of operands!");
819 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
822 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 1 && "Invalid number of operands!");
824 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
827 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
828 assert(N == 1 && "Invalid number of operands!");
829 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
830 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
831 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
832 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
836 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
837 assert(N == 1 && "Invalid number of operands!");
838 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
841 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
842 assert(N == 1 && "Invalid number of operands!");
843 Inst.addOperand(MCOperand::createReg(getFCCReg()));
846 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
847 assert(N == 1 && "Invalid number of operands!");
848 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
851 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
852 assert(N == 1 && "Invalid number of operands!");
853 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
856 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
857 assert(N == 1 && "Invalid number of operands!");
858 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
861 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
862 assert(N == 1 && "Invalid number of operands!");
863 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
866 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
867 assert(N == 1 && "Invalid number of operands!");
868 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
871 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
872 assert(N == 1 && "Invalid number of operands!");
873 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
876 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
877 assert(N == 1 && "Invalid number of operands!");
878 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
881 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
882 assert(N == 1 && "Invalid number of operands!");
883 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
886 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
887 assert(N == 1 && "Invalid number of operands!");
888 Inst.addOperand(MCOperand::createReg(getCCRReg()));
891 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
892 assert(N == 1 && "Invalid number of operands!");
893 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
896 template <unsigned Bits, int Offset = 0>
897 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
898 assert(N == 1 && "Invalid number of operands!");
899 uint64_t Imm = getConstantImm() - Offset;
900 Imm &= (1 << Bits) - 1;
902 Inst.addOperand(MCOperand::createImm(Imm));
905 void addImmOperands(MCInst &Inst, unsigned N) const {
906 assert(N == 1 && "Invalid number of operands!");
907 const MCExpr *Expr = getImm();
911 void addMemOperands(MCInst &Inst, unsigned N) const {
912 assert(N == 2 && "Invalid number of operands!");
914 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
915 ? getMemBase()->getGPR64Reg()
916 : getMemBase()->getGPR32Reg()));
918 const MCExpr *Expr = getMemOff();
922 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
923 assert(N == 2 && "Invalid number of operands!");
925 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
927 const MCExpr *Expr = getMemOff();
931 void addRegListOperands(MCInst &Inst, unsigned N) const {
932 assert(N == 1 && "Invalid number of operands!");
934 for (auto RegNo : getRegList())
935 Inst.addOperand(MCOperand::createReg(RegNo));
938 void addRegPairOperands(MCInst &Inst, unsigned N) const {
939 assert(N == 2 && "Invalid number of operands!");
940 unsigned RegNo = getRegPair();
941 Inst.addOperand(MCOperand::createReg(RegNo++));
942 Inst.addOperand(MCOperand::createReg(RegNo));
945 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
946 assert(N == 2 && "Invalid number of operands!");
947 for (auto RegNo : getRegList())
948 Inst.addOperand(MCOperand::createReg(RegNo));
951 bool isReg() const override {
952 // As a special case until we sort out the definition of div/divu, pretend
953 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
954 if (isGPRAsmReg() && RegIdx.Index == 0)
957 return Kind == k_PhysRegister;
959 bool isRegIdx() const { return Kind == k_RegisterIndex; }
960 bool isImm() const override { return Kind == k_Immediate; }
961 bool isConstantImm() const {
962 return isImm() && dyn_cast<MCConstantExpr>(getImm());
964 bool isConstantImmz() const {
965 return isConstantImm() && getConstantImm() == 0;
967 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
968 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
970 template <unsigned Bits> bool isUImm() const {
971 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
973 bool isToken() const override {
974 // Note: It's not possible to pretend that other operand kinds are tokens.
975 // The matcher emitter checks tokens first.
976 return Kind == k_Token;
978 bool isMem() const override { return Kind == k_Memory; }
979 bool isConstantMemOff() const {
980 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
982 template <unsigned Bits> bool isMemWithSimmOffset() const {
983 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
984 && getMemBase()->isGPRAsmReg();
986 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
987 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
988 getMemBase()->isGPRAsmReg();
990 bool isMemWithGRPMM16Base() const {
991 return isMem() && getMemBase()->isMM16AsmReg();
993 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
994 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
995 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
997 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
998 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
999 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1000 && (getMemBase()->getGPR32Reg() == Mips::SP);
1002 bool isUImm5Lsl2() const {
1003 return (isImm() && isConstantImm() && isShiftedUInt<5, 2>(getConstantImm()));
1005 bool isRegList16() const {
1009 int Size = RegList.List->size();
1010 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
1011 RegList.List->back() != Mips::RA)
1014 int PrevReg = *RegList.List->begin();
1015 for (int i = 1; i < Size - 1; i++) {
1016 int Reg = (*(RegList.List))[i];
1017 if ( Reg != PrevReg + 1)
1024 bool isInvNum() const { return Kind == k_Immediate; }
1025 bool isLSAImm() const {
1026 if (!isConstantImm())
1028 int64_t Val = getConstantImm();
1029 return 1 <= Val && Val <= 4;
1031 bool isRegList() const { return Kind == k_RegList; }
1032 bool isMovePRegPair() const {
1033 if (Kind != k_RegList || RegList.List->size() != 2)
1036 unsigned R0 = RegList.List->front();
1037 unsigned R1 = RegList.List->back();
1039 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1040 (R0 == Mips::A1 && R1 == Mips::A3) ||
1041 (R0 == Mips::A2 && R1 == Mips::A3) ||
1042 (R0 == Mips::A0 && R1 == Mips::S5) ||
1043 (R0 == Mips::A0 && R1 == Mips::S6) ||
1044 (R0 == Mips::A0 && R1 == Mips::A1) ||
1045 (R0 == Mips::A0 && R1 == Mips::A2) ||
1046 (R0 == Mips::A0 && R1 == Mips::A3))
1052 StringRef getToken() const {
1053 assert(Kind == k_Token && "Invalid access!");
1054 return StringRef(Tok.Data, Tok.Length);
1056 bool isRegPair() const { return Kind == k_RegPair; }
1058 unsigned getReg() const override {
1059 // As a special case until we sort out the definition of div/divu, pretend
1060 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1061 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1062 RegIdx.Kind & RegKind_GPR)
1063 return getGPR32Reg(); // FIXME: GPR64 too
1065 assert(Kind == k_PhysRegister && "Invalid access!");
1069 const MCExpr *getImm() const {
1070 assert((Kind == k_Immediate) && "Invalid access!");
1074 int64_t getConstantImm() const {
1075 const MCExpr *Val = getImm();
1076 return static_cast<const MCConstantExpr *>(Val)->getValue();
1079 MipsOperand *getMemBase() const {
1080 assert((Kind == k_Memory) && "Invalid access!");
1084 const MCExpr *getMemOff() const {
1085 assert((Kind == k_Memory) && "Invalid access!");
1089 int64_t getConstantMemOff() const {
1090 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1093 const SmallVectorImpl<unsigned> &getRegList() const {
1094 assert((Kind == k_RegList) && "Invalid access!");
1095 return *(RegList.List);
1098 unsigned getRegPair() const {
1099 assert((Kind == k_RegPair) && "Invalid access!");
1100 return RegIdx.Index;
1103 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1104 MipsAsmParser &Parser) {
1105 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1106 Op->Tok.Data = Str.data();
1107 Op->Tok.Length = Str.size();
1113 /// Create a numeric register (e.g. $1). The exact register remains
1114 /// unresolved until an instruction successfully matches
1115 static std::unique_ptr<MipsOperand>
1116 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1117 SMLoc E, MipsAsmParser &Parser) {
1118 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1119 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1122 /// Create a register that is definitely a GPR.
1123 /// This is typically only used for named registers such as $gp.
1124 static std::unique_ptr<MipsOperand>
1125 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1126 MipsAsmParser &Parser) {
1127 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1130 /// Create a register that is definitely a FGR.
1131 /// This is typically only used for named registers such as $f0.
1132 static std::unique_ptr<MipsOperand>
1133 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1134 MipsAsmParser &Parser) {
1135 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1138 /// Create a register that is definitely a HWReg.
1139 /// This is typically only used for named registers such as $hwr_cpunum.
1140 static std::unique_ptr<MipsOperand>
1141 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1142 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1143 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1146 /// Create a register that is definitely an FCC.
1147 /// This is typically only used for named registers such as $fcc0.
1148 static std::unique_ptr<MipsOperand>
1149 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1150 MipsAsmParser &Parser) {
1151 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1154 /// Create a register that is definitely an ACC.
1155 /// This is typically only used for named registers such as $ac0.
1156 static std::unique_ptr<MipsOperand>
1157 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1158 MipsAsmParser &Parser) {
1159 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1162 /// Create a register that is definitely an MSA128.
1163 /// This is typically only used for named registers such as $w0.
1164 static std::unique_ptr<MipsOperand>
1165 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1166 SMLoc E, MipsAsmParser &Parser) {
1167 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1170 /// Create a register that is definitely an MSACtrl.
1171 /// This is typically only used for named registers such as $msaaccess.
1172 static std::unique_ptr<MipsOperand>
1173 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1174 SMLoc E, MipsAsmParser &Parser) {
1175 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1178 static std::unique_ptr<MipsOperand>
1179 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1180 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1187 static std::unique_ptr<MipsOperand>
1188 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1189 SMLoc E, MipsAsmParser &Parser) {
1190 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1191 Op->Mem.Base = Base.release();
1198 static std::unique_ptr<MipsOperand>
1199 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1200 MipsAsmParser &Parser) {
1201 assert (Regs.size() > 0 && "Empty list not allowed");
1203 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1204 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1205 Op->StartLoc = StartLoc;
1206 Op->EndLoc = EndLoc;
1210 static std::unique_ptr<MipsOperand>
1211 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1212 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1213 Op->RegIdx.Index = RegNo;
1219 bool isGPRAsmReg() const {
1220 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1222 bool isMM16AsmReg() const {
1223 if (!(isRegIdx() && RegIdx.Kind))
1225 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1226 || RegIdx.Index == 16 || RegIdx.Index == 17);
1228 bool isMM16AsmRegZero() const {
1229 if (!(isRegIdx() && RegIdx.Kind))
1231 return (RegIdx.Index == 0 ||
1232 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1233 RegIdx.Index == 17);
1235 bool isMM16AsmRegMoveP() const {
1236 if (!(isRegIdx() && RegIdx.Kind))
1238 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1239 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1241 bool isFGRAsmReg() const {
1242 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1243 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1245 bool isHWRegsAsmReg() const {
1246 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1248 bool isCCRAsmReg() const {
1249 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1251 bool isFCCAsmReg() const {
1252 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1254 if (!AsmParser.hasEightFccRegisters())
1255 return RegIdx.Index == 0;
1256 return RegIdx.Index <= 7;
1258 bool isACCAsmReg() const {
1259 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1261 bool isCOP0AsmReg() const {
1262 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1264 bool isCOP2AsmReg() const {
1265 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1267 bool isCOP3AsmReg() const {
1268 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1270 bool isMSA128AsmReg() const {
1271 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1273 bool isMSACtrlAsmReg() const {
1274 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1277 /// getStartLoc - Get the location of the first token of this operand.
1278 SMLoc getStartLoc() const override { return StartLoc; }
1279 /// getEndLoc - Get the location of the last token of this operand.
1280 SMLoc getEndLoc() const override { return EndLoc; }
1282 virtual ~MipsOperand() {
1290 delete RegList.List;
1291 case k_PhysRegister:
1292 case k_RegisterIndex:
1299 void print(raw_ostream &OS) const override {
1308 Mem.Base->print(OS);
1313 case k_PhysRegister:
1314 OS << "PhysReg<" << PhysReg.Num << ">";
1316 case k_RegisterIndex:
1317 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1324 for (auto Reg : (*RegList.List))
1329 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1333 }; // class MipsOperand
1337 extern const MCInstrDesc MipsInsts[];
1339 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1340 return MipsInsts[Opcode];
1343 static bool hasShortDelaySlot(unsigned Opcode) {
1346 case Mips::JALRS_MM:
1347 case Mips::JALRS16_MM:
1348 case Mips::BGEZALS_MM:
1349 case Mips::BLTZALS_MM:
1356 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1357 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1358 return &SRExpr->getSymbol();
1361 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1362 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1363 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1374 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1375 return getSingleMCSymbol(UExpr->getSubExpr());
1380 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1381 if (isa<MCSymbolRefExpr>(Expr))
1384 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1385 return countMCSymbolRefExpr(BExpr->getLHS()) +
1386 countMCSymbolRefExpr(BExpr->getRHS());
1388 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1389 return countMCSymbolRefExpr(UExpr->getSubExpr());
1395 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1396 SmallVectorImpl<MCInst> &Instructions) {
1398 tmpInst.setOpcode(Opcode);
1399 tmpInst.addOperand(MCOperand::createReg(Reg0));
1400 tmpInst.addOperand(Op1);
1401 tmpInst.setLoc(IDLoc);
1402 Instructions.push_back(tmpInst);
1405 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1406 SmallVectorImpl<MCInst> &Instructions) {
1407 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1410 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1411 SmallVectorImpl<MCInst> &Instructions) {
1412 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1415 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1416 SmallVectorImpl<MCInst> &Instructions) {
1418 tmpInst.setOpcode(Opcode);
1419 tmpInst.addOperand(MCOperand::createImm(Imm1));
1420 tmpInst.addOperand(MCOperand::createImm(Imm2));
1421 tmpInst.setLoc(IDLoc);
1422 Instructions.push_back(tmpInst);
1425 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1426 SmallVectorImpl<MCInst> &Instructions) {
1428 tmpInst.setOpcode(Opcode);
1429 tmpInst.addOperand(MCOperand::createReg(Reg0));
1430 tmpInst.setLoc(IDLoc);
1431 Instructions.push_back(tmpInst);
1434 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1435 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1437 tmpInst.setOpcode(Opcode);
1438 tmpInst.addOperand(MCOperand::createReg(Reg0));
1439 tmpInst.addOperand(MCOperand::createReg(Reg1));
1440 tmpInst.addOperand(Op2);
1441 tmpInst.setLoc(IDLoc);
1442 Instructions.push_back(tmpInst);
1445 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1446 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1447 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1451 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1452 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1453 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1457 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1458 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1459 if (ShiftAmount >= 32) {
1460 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1465 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1467 } // end anonymous namespace.
1469 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1470 SmallVectorImpl<MCInst> &Instructions) {
1471 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1472 bool ExpandedJalSym = false;
1476 if (MCID.isBranch() || MCID.isCall()) {
1477 const unsigned Opcode = Inst.getOpcode();
1487 assert(hasCnMips() && "instruction only valid for octeon cpus");
1494 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1495 Offset = Inst.getOperand(2);
1496 if (!Offset.isImm())
1497 break; // We'll deal with this situation later on when applying fixups.
1498 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1499 return Error(IDLoc, "branch target out of range");
1500 if (OffsetToAlignment(Offset.getImm(),
1501 1LL << (inMicroMipsMode() ? 1 : 2)))
1502 return Error(IDLoc, "branch to misaligned address");
1516 case Mips::BGEZAL_MM:
1517 case Mips::BLTZAL_MM:
1520 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1521 Offset = Inst.getOperand(1);
1522 if (!Offset.isImm())
1523 break; // We'll deal with this situation later on when applying fixups.
1524 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1525 return Error(IDLoc, "branch target out of range");
1526 if (OffsetToAlignment(Offset.getImm(),
1527 1LL << (inMicroMipsMode() ? 1 : 2)))
1528 return Error(IDLoc, "branch to misaligned address");
1530 case Mips::BEQZ16_MM:
1531 case Mips::BEQZC16_MMR6:
1532 case Mips::BNEZ16_MM:
1533 case Mips::BNEZC16_MMR6:
1534 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1535 Offset = Inst.getOperand(1);
1536 if (!Offset.isImm())
1537 break; // We'll deal with this situation later on when applying fixups.
1538 if (!isInt<8>(Offset.getImm()))
1539 return Error(IDLoc, "branch target out of range");
1540 if (OffsetToAlignment(Offset.getImm(), 2LL))
1541 return Error(IDLoc, "branch to misaligned address");
1546 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1547 // We still accept it but it is a normal nop.
1548 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1549 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1550 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1555 const unsigned Opcode = Inst.getOpcode();
1567 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1568 // The offset is handled above
1569 Opnd = Inst.getOperand(1);
1571 return Error(IDLoc, "expected immediate operand kind");
1572 Imm = Opnd.getImm();
1573 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1574 Opcode == Mips::BBIT1 ? 63 : 31))
1575 return Error(IDLoc, "immediate operand value out of range");
1577 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1579 Inst.getOperand(1).setImm(Imm - 32);
1587 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1589 Opnd = Inst.getOperand(3);
1591 return Error(IDLoc, "expected immediate operand kind");
1592 Imm = Opnd.getImm();
1593 if (Imm < 0 || Imm > 31)
1594 return Error(IDLoc, "immediate operand value out of range");
1596 Opnd = Inst.getOperand(2);
1598 return Error(IDLoc, "expected immediate operand kind");
1599 Imm = Opnd.getImm();
1600 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1601 Opcode == Mips::EXTS ? 63 : 31))
1602 return Error(IDLoc, "immediate operand value out of range");
1604 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1605 Inst.getOperand(2).setImm(Imm - 32);
1611 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1612 Opnd = Inst.getOperand(2);
1614 return Error(IDLoc, "expected immediate operand kind");
1615 Imm = Opnd.getImm();
1616 if (!isInt<10>(Imm))
1617 return Error(IDLoc, "immediate operand value out of range");
1622 // This expansion is not in a function called by tryExpandInstruction()
1623 // because the pseudo-instruction doesn't have a distinct opcode.
1624 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1626 warnIfNoMacro(IDLoc);
1628 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1630 // We can do this expansion if there's only 1 symbol in the argument
1632 if (countMCSymbolRefExpr(JalExpr) > 1)
1633 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1635 // FIXME: This is checking the expression can be handled by the later stages
1636 // of the assembler. We ought to leave it to those later stages but
1637 // we can't do that until we stop evaluateRelocExpr() rewriting the
1638 // expressions into non-equivalent forms.
1639 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1641 // FIXME: Add support for label+offset operands (currently causes an error).
1642 // FIXME: Add support for forward-declared local symbols.
1643 // FIXME: Add expansion for when the LargeGOT option is enabled.
1644 if (JalSym->isInSection() || JalSym->isTemporary()) {
1646 // If it's a local symbol and the O32 ABI is being used, we expand to:
1648 // R_(MICRO)MIPS_GOT16 label
1649 // addiu $25, $25, 0
1650 // R_(MICRO)MIPS_LO16 label
1652 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1653 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1655 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1656 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1657 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1658 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1659 } else if (isABI_N32() || isABI_N64()) {
1660 // If it's a local symbol and the N32/N64 ABIs are being used,
1662 // lw/ld $25, 0($gp)
1663 // R_(MICRO)MIPS_GOT_DISP label
1665 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1667 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1668 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1671 // If it's an external/weak symbol, we expand to:
1672 // lw/ld $25, 0($gp)
1673 // R_(MICRO)MIPS_CALL16 label
1675 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1677 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1678 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1682 if (IsCpRestoreSet && inMicroMipsMode())
1683 JalrInst.setOpcode(Mips::JALRS_MM);
1685 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1686 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1687 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1689 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1690 // This relocation is supposed to be an optimization hint for the linker
1691 // and is not necessary for correctness.
1694 ExpandedJalSym = true;
1697 if (MCID.mayLoad() || MCID.mayStore()) {
1698 // Check the offset of memory operand, if it is a symbol
1699 // reference or immediate we may have to expand instructions.
1700 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1701 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1702 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1703 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1704 MCOperand &Op = Inst.getOperand(i);
1706 int MemOffset = Op.getImm();
1707 if (MemOffset < -32768 || MemOffset > 32767) {
1708 // Offset can't exceed 16bit value.
1709 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1712 } else if (Op.isExpr()) {
1713 const MCExpr *Expr = Op.getExpr();
1714 if (Expr->getKind() == MCExpr::SymbolRef) {
1715 const MCSymbolRefExpr *SR =
1716 static_cast<const MCSymbolRefExpr *>(Expr);
1717 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1719 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1722 } else if (!isEvaluated(Expr)) {
1723 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1731 if (inMicroMipsMode()) {
1732 if (MCID.mayLoad()) {
1733 // Try to create 16-bit GP relative load instruction.
1734 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1735 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1736 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1737 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1738 MCOperand &Op = Inst.getOperand(i);
1740 int MemOffset = Op.getImm();
1741 MCOperand &DstReg = Inst.getOperand(0);
1742 MCOperand &BaseReg = Inst.getOperand(1);
1743 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1744 getContext().getRegisterInfo()->getRegClass(
1745 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1746 (BaseReg.getReg() == Mips::GP ||
1747 BaseReg.getReg() == Mips::GP_64)) {
1749 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1750 IDLoc, Instructions);
1758 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1763 switch (Inst.getOpcode()) {
1766 case Mips::ADDIUS5_MM:
1767 Opnd = Inst.getOperand(2);
1769 return Error(IDLoc, "expected immediate operand kind");
1770 Imm = Opnd.getImm();
1771 if (Imm < -8 || Imm > 7)
1772 return Error(IDLoc, "immediate operand value out of range");
1774 case Mips::ADDIUSP_MM:
1775 Opnd = Inst.getOperand(0);
1777 return Error(IDLoc, "expected immediate operand kind");
1778 Imm = Opnd.getImm();
1779 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1781 return Error(IDLoc, "immediate operand value out of range");
1783 case Mips::SLL16_MM:
1784 case Mips::SRL16_MM:
1785 Opnd = Inst.getOperand(2);
1787 return Error(IDLoc, "expected immediate operand kind");
1788 Imm = Opnd.getImm();
1789 if (Imm < 1 || Imm > 8)
1790 return Error(IDLoc, "immediate operand value out of range");
1793 Opnd = Inst.getOperand(1);
1795 return Error(IDLoc, "expected immediate operand kind");
1796 Imm = Opnd.getImm();
1797 if (Imm < -1 || Imm > 126)
1798 return Error(IDLoc, "immediate operand value out of range");
1800 case Mips::ADDIUR2_MM:
1801 Opnd = Inst.getOperand(2);
1803 return Error(IDLoc, "expected immediate operand kind");
1804 Imm = Opnd.getImm();
1805 if (!(Imm == 1 || Imm == -1 ||
1806 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1807 return Error(IDLoc, "immediate operand value out of range");
1809 case Mips::ADDIUR1SP_MM:
1810 Opnd = Inst.getOperand(1);
1812 return Error(IDLoc, "expected immediate operand kind");
1813 Imm = Opnd.getImm();
1814 if (OffsetToAlignment(Imm, 4LL))
1815 return Error(IDLoc, "misaligned immediate operand value");
1816 if (Imm < 0 || Imm > 255)
1817 return Error(IDLoc, "immediate operand value out of range");
1819 case Mips::ANDI16_MM:
1820 Opnd = Inst.getOperand(2);
1822 return Error(IDLoc, "expected immediate operand kind");
1823 Imm = Opnd.getImm();
1824 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1825 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1826 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1827 return Error(IDLoc, "immediate operand value out of range");
1829 case Mips::LBU16_MM:
1830 Opnd = Inst.getOperand(2);
1832 return Error(IDLoc, "expected immediate operand kind");
1833 Imm = Opnd.getImm();
1834 if (Imm < -1 || Imm > 14)
1835 return Error(IDLoc, "immediate operand value out of range");
1844 Opnd = Inst.getOperand(2);
1846 return Error(IDLoc, "expected immediate operand kind");
1847 Imm = Opnd.getImm();
1848 if (Imm < 0 || Imm > 15)
1849 return Error(IDLoc, "immediate operand value out of range");
1851 case Mips::LHU16_MM:
1853 Opnd = Inst.getOperand(2);
1855 return Error(IDLoc, "expected immediate operand kind");
1856 Imm = Opnd.getImm();
1857 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1858 return Error(IDLoc, "immediate operand value out of range");
1862 Opnd = Inst.getOperand(2);
1864 return Error(IDLoc, "expected immediate operand kind");
1865 Imm = Opnd.getImm();
1866 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1867 return Error(IDLoc, "immediate operand value out of range");
1869 case Mips::PREFX_MM:
1872 Opnd = Inst.getOperand(2);
1874 return Error(IDLoc, "expected immediate operand kind");
1875 Imm = Opnd.getImm();
1876 if (!isUInt<5>(Imm))
1877 return Error(IDLoc, "immediate operand value out of range");
1879 case Mips::ADDIUPC_MM:
1880 MCOperand Opnd = Inst.getOperand(1);
1882 return Error(IDLoc, "expected immediate operand kind");
1883 int Imm = Opnd.getImm();
1884 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1885 return Error(IDLoc, "immediate operand value out of range");
1890 MacroExpanderResultTy ExpandResult =
1891 tryExpandInstruction(Inst, IDLoc, Instructions);
1892 switch (ExpandResult) {
1894 Instructions.push_back(Inst);
1902 // If this instruction has a delay slot and .set reorder is active,
1903 // emit a NOP after it.
1904 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1905 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1907 if ((Inst.getOpcode() == Mips::JalOneReg ||
1908 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1909 isPicAndNotNxxAbi()) {
1910 if (IsCpRestoreSet) {
1911 // We need a NOP between the JALR and the LW:
1912 // If .set reorder has been used, we've already emitted a NOP.
1913 // If .set noreorder has been used, we need to emit a NOP at this point.
1914 if (!AssemblerOptions.back()->isReorder())
1915 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1917 // Load the $gp from the stack.
1918 SmallVector<MCInst, 3> LoadInsts;
1919 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1922 for (const MCInst &Inst : LoadInsts)
1923 Instructions.push_back(Inst);
1926 Warning(IDLoc, "no .cprestore used in PIC mode");
1932 MipsAsmParser::MacroExpanderResultTy
1933 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
1934 SmallVectorImpl<MCInst> &Instructions) {
1935 switch (Inst.getOpcode()) {
1937 return MER_NotAMacro;
1938 case Mips::LoadImm32:
1939 return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
1941 case Mips::LoadImm64:
1942 return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
1944 case Mips::LoadAddrImm32:
1945 case Mips::LoadAddrImm64:
1946 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1947 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1948 "expected immediate operand kind");
1950 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
1952 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1956 case Mips::LoadAddrReg32:
1957 case Mips::LoadAddrReg64:
1958 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1959 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1960 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1961 "expected immediate operand kind");
1963 return expandLoadAddress(Inst.getOperand(0).getReg(),
1964 Inst.getOperand(1).getReg(), Inst.getOperand(2),
1965 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
1969 case Mips::B_MM_Pseudo:
1970 case Mips::B_MMR6_Pseudo:
1971 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
1975 return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
1977 case Mips::JalOneReg:
1978 case Mips::JalTwoReg:
1979 return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
1983 return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2000 case Mips::BLTImmMacro:
2001 case Mips::BLEImmMacro:
2002 case Mips::BGEImmMacro:
2003 case Mips::BGTImmMacro:
2004 case Mips::BLTUImmMacro:
2005 case Mips::BLEUImmMacro:
2006 case Mips::BGEUImmMacro:
2007 case Mips::BGTUImmMacro:
2008 case Mips::BLTLImmMacro:
2009 case Mips::BLELImmMacro:
2010 case Mips::BGELImmMacro:
2011 case Mips::BGTLImmMacro:
2012 case Mips::BLTULImmMacro:
2013 case Mips::BLEULImmMacro:
2014 case Mips::BGEULImmMacro:
2015 case Mips::BGTULImmMacro:
2016 return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2018 case Mips::SDivMacro:
2019 return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2021 case Mips::DSDivMacro:
2022 return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2024 case Mips::UDivMacro:
2025 return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2027 case Mips::DUDivMacro:
2028 return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2031 return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2033 return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2035 return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2037 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2043 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2044 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2045 int64_t ImmValue = Inst.getOperand(2).getImm();
2046 if (isInt<16>(ImmValue))
2047 return MER_NotAMacro;
2048 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2051 return MER_NotAMacro;
2055 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2056 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2057 int64_t ImmValue = Inst.getOperand(2).getImm();
2058 if (isUInt<16>(ImmValue))
2059 return MER_NotAMacro;
2060 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2063 return MER_NotAMacro;
2067 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2068 SmallVectorImpl<MCInst> &Instructions) {
2069 // Create a JALR instruction which is going to replace the pseudo-JAL.
2071 JalrInst.setLoc(IDLoc);
2072 const MCOperand FirstRegOp = Inst.getOperand(0);
2073 const unsigned Opcode = Inst.getOpcode();
2075 if (Opcode == Mips::JalOneReg) {
2076 // jal $rs => jalr $rs
2077 if (IsCpRestoreSet && inMicroMipsMode()) {
2078 JalrInst.setOpcode(Mips::JALRS16_MM);
2079 JalrInst.addOperand(FirstRegOp);
2080 } else if (inMicroMipsMode()) {
2081 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2082 JalrInst.addOperand(FirstRegOp);
2084 JalrInst.setOpcode(Mips::JALR);
2085 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2086 JalrInst.addOperand(FirstRegOp);
2088 } else if (Opcode == Mips::JalTwoReg) {
2089 // jal $rd, $rs => jalr $rd, $rs
2090 if (IsCpRestoreSet && inMicroMipsMode())
2091 JalrInst.setOpcode(Mips::JALRS_MM);
2093 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2094 JalrInst.addOperand(FirstRegOp);
2095 const MCOperand SecondRegOp = Inst.getOperand(1);
2096 JalrInst.addOperand(SecondRegOp);
2098 Instructions.push_back(JalrInst);
2100 // If .set reorder is active and branch instruction has a delay slot,
2101 // emit a NOP after it.
2102 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2103 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2104 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2110 /// Can the value be represented by a unsigned N-bit value and a shift left?
2111 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2112 unsigned BitNum = findFirstSet(x);
2114 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2117 /// Load (or add) an immediate into a register.
2119 /// @param ImmValue The immediate to load.
2120 /// @param DstReg The register that will hold the immediate.
2121 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2122 /// for a simple initialization.
2123 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2124 /// @param IsAddress True if the immediate represents an address. False if it
2126 /// @param IDLoc Location of the immediate in the source file.
2127 /// @param Instructions The instructions emitted by this expansion.
2128 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2129 unsigned SrcReg, bool Is32BitImm,
2130 bool IsAddress, SMLoc IDLoc,
2131 SmallVectorImpl<MCInst> &Instructions) {
2132 if (!Is32BitImm && !isGP64bit()) {
2133 Error(IDLoc, "instruction requires a 64-bit architecture");
2138 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2139 // Sign extend up to 64-bit so that the predicates match the hardware
2140 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2142 ImmValue = SignExtend64<32>(ImmValue);
2144 Error(IDLoc, "instruction requires a 32-bit immediate");
2149 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2150 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2152 bool UseSrcReg = false;
2153 if (SrcReg != Mips::NoRegister)
2156 unsigned TmpReg = DstReg;
2157 if (UseSrcReg && (DstReg == SrcReg)) {
2158 // At this point we need AT to perform the expansions and we exit if it is
2160 unsigned ATReg = getATReg(IDLoc);
2166 if (isInt<16>(ImmValue)) {
2170 // This doesn't quite follow the usual ABI expectations for N32 but matches
2171 // traditional assembler behaviour. N32 would normally use addiu for both
2172 // integers and addresses.
2173 if (IsAddress && !Is32BitImm) {
2174 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2178 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2182 if (isUInt<16>(ImmValue)) {
2183 unsigned TmpReg = DstReg;
2184 if (SrcReg == DstReg) {
2185 TmpReg = getATReg(IDLoc);
2190 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2192 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2196 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2197 warnIfNoMacro(IDLoc);
2199 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2200 uint16_t Bits15To0 = ImmValue & 0xffff;
2202 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2203 // Traditional behaviour seems to special case this particular value. It's
2204 // not clear why other masks are handled differently.
2205 if (ImmValue == 0xffffffff) {
2206 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2207 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2209 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2213 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2215 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2216 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2218 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2220 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2224 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2226 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2228 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2232 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2234 Error(IDLoc, "instruction requires a 32-bit immediate");
2238 // Traditionally, these immediates are shifted as little as possible and as
2239 // such we align the most significant bit to bit 15 of our temporary.
2240 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2241 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2242 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2243 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2244 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2245 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2248 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2253 warnIfNoMacro(IDLoc);
2255 // The remaining case is packed with a sequence of dsll and ori with zeros
2256 // being omitted and any neighbouring dsll's being coalesced.
2257 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2259 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2260 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2261 IDLoc, Instructions))
2264 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2265 // skip it and defer the shift to the next chunk.
2266 unsigned ShiftCarriedForwards = 16;
2267 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2268 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2270 if (ImmChunk != 0) {
2271 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2273 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2274 ShiftCarriedForwards = 0;
2277 ShiftCarriedForwards += 16;
2279 ShiftCarriedForwards -= 16;
2281 // Finish any remaining shifts left by trailing zeros.
2282 if (ShiftCarriedForwards)
2283 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2287 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2292 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2293 SmallVectorImpl<MCInst> &Instructions) {
2294 const MCOperand &ImmOp = Inst.getOperand(1);
2295 assert(ImmOp.isImm() && "expected immediate operand kind");
2296 const MCOperand &DstRegOp = Inst.getOperand(0);
2297 assert(DstRegOp.isReg() && "expected register operand kind");
2299 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2300 Is32BitImm, false, IDLoc, Instructions))
2306 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2307 const MCOperand &Offset,
2308 bool Is32BitAddress, SMLoc IDLoc,
2309 SmallVectorImpl<MCInst> &Instructions) {
2310 // la can't produce a usable address when addresses are 64-bit.
2311 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2312 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2313 // We currently can't do this because we depend on the equality
2314 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2315 Error(IDLoc, "la used to load 64-bit address");
2316 // Continue as if we had 'dla' instead.
2317 Is32BitAddress = false;
2320 // dla requires 64-bit addresses.
2321 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2322 Error(IDLoc, "instruction requires a 64-bit architecture");
2326 if (!Offset.isImm())
2327 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2328 Is32BitAddress, IDLoc, Instructions);
2330 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2331 IDLoc, Instructions);
2334 bool MipsAsmParser::loadAndAddSymbolAddress(
2335 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2336 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2337 warnIfNoMacro(IDLoc);
2339 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2340 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2341 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2342 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2343 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2345 bool UseSrcReg = SrcReg != Mips::NoRegister;
2347 // This is the 64-bit symbol address expansion.
2348 if (ABI.ArePtrs64bit() && isGP64bit()) {
2349 // We always need AT for the 64-bit expansion.
2350 // If it is not available we exit.
2351 unsigned ATReg = getATReg(IDLoc);
2355 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2356 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2357 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2358 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2360 if (UseSrcReg && (DstReg == SrcReg)) {
2361 // If $rs is the same as $rd:
2362 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2363 // daddiu $at, $at, %higher(sym)
2364 // dsll $at, $at, 16
2365 // daddiu $at, $at, %hi(sym)
2366 // dsll $at, $at, 16
2367 // daddiu $at, $at, %lo(sym)
2368 // daddu $rd, $at, $rd
2369 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2371 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2372 IDLoc, Instructions);
2373 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2374 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2376 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2377 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2379 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2384 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2385 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2386 // lui $at, %hi(sym)
2387 // daddiu $rd, $rd, %higher(sym)
2388 // daddiu $at, $at, %lo(sym)
2389 // dsll32 $rd, $rd, 0
2390 // daddu $rd, $rd, $at
2391 // (daddu $rd, $rd, $rs)
2392 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2394 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2396 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2397 IDLoc, Instructions);
2398 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2400 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2401 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2403 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2408 // And now, the 32-bit symbol address expansion:
2409 // If $rs is the same as $rd:
2410 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2411 // ori $at, $at, %lo(sym)
2412 // addu $rd, $at, $rd
2413 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2414 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2415 // ori $rd, $rd, %lo(sym)
2416 // (addu $rd, $rd, $rs)
2417 unsigned TmpReg = DstReg;
2418 if (UseSrcReg && (DstReg == SrcReg)) {
2419 // If $rs is the same as $rd, we need to use AT.
2420 // If it is not available we exit.
2421 unsigned ATReg = getATReg(IDLoc);
2427 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2428 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2432 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2434 assert(DstReg == TmpReg);
2439 bool MipsAsmParser::expandUncondBranchMMPseudo(
2440 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2441 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2442 "unexpected number of operands");
2444 MCOperand Offset = Inst.getOperand(0);
2445 if (Offset.isExpr()) {
2447 Inst.setOpcode(Mips::BEQ_MM);
2448 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2449 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2450 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2452 assert(Offset.isImm() && "expected immediate operand kind");
2453 if (isInt<11>(Offset.getImm())) {
2454 // If offset fits into 11 bits then this instruction becomes microMIPS
2455 // 16-bit unconditional branch instruction.
2456 if (inMicroMipsMode())
2457 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2459 if (!isInt<17>(Offset.getImm()))
2460 Error(IDLoc, "branch target out of range");
2461 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2462 Error(IDLoc, "branch to misaligned address");
2464 Inst.setOpcode(Mips::BEQ_MM);
2465 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2466 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2467 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2470 Instructions.push_back(Inst);
2472 // If .set reorder is active and branch instruction has a delay slot,
2473 // emit a NOP after it.
2474 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2475 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2476 createNop(true, IDLoc, Instructions);
2481 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2482 SmallVectorImpl<MCInst> &Instructions) {
2483 const MCOperand &DstRegOp = Inst.getOperand(0);
2484 assert(DstRegOp.isReg() && "expected register operand kind");
2486 const MCOperand &ImmOp = Inst.getOperand(1);
2487 assert(ImmOp.isImm() && "expected immediate operand kind");
2489 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2490 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2492 unsigned OpCode = 0;
2493 switch(Inst.getOpcode()) {
2501 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2505 int64_t ImmValue = ImmOp.getImm();
2507 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2510 warnIfNoMacro(IDLoc);
2512 unsigned ATReg = getATReg(IDLoc);
2516 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2517 IDLoc, Instructions))
2520 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2525 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2526 SmallVectorImpl<MCInst> &Instructions,
2527 bool isLoad, bool isImmOpnd) {
2528 unsigned ImmOffset, HiOffset, LoOffset;
2529 const MCExpr *ExprOffset;
2531 // 1st operand is either the source or destination register.
2532 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2533 unsigned RegOpNum = Inst.getOperand(0).getReg();
2534 // 2nd operand is the base register.
2535 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2536 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2537 // 3rd operand is either an immediate or expression.
2539 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2540 ImmOffset = Inst.getOperand(2).getImm();
2541 LoOffset = ImmOffset & 0x0000ffff;
2542 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2543 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2544 if (LoOffset & 0x8000)
2547 ExprOffset = Inst.getOperand(2).getExpr();
2548 // These are some of the types of expansions we perform here:
2549 // 1) lw $8, sym => lui $8, %hi(sym)
2550 // lw $8, %lo(sym)($8)
2551 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2553 // lw $8, %lo(offset)($9)
2554 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2556 // lw $8, %lo(offset)($at)
2557 // 4) sw $8, sym => lui $at, %hi(sym)
2558 // sw $8, %lo(sym)($at)
2559 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2561 // sw $8, %lo(offset)($at)
2562 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2563 // ldc1 $f0, %lo(sym)($at)
2565 // For load instructions we can use the destination register as a temporary
2566 // if base and dst are different (examples 1 and 2) and if the base register
2567 // is general purpose otherwise we must use $at (example 6) and error if it's
2568 // not available. For stores we must use $at (examples 4 and 5) because we
2569 // must not clobber the source register setting up the offset.
2570 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2571 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2572 unsigned RegClassIDOp0 =
2573 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2574 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2575 (RegClassIDOp0 == Mips::GPR64RegClassID);
2576 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2577 TmpRegNum = RegOpNum;
2579 // At this point we need AT to perform the expansions and we exit if it is
2581 TmpRegNum = getATReg(IDLoc);
2586 emitRX(Mips::LUi, TmpRegNum,
2587 isImmOpnd ? MCOperand::createImm(HiOffset)
2588 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2589 IDLoc, Instructions);
2590 // Add temp register to base.
2591 if (BaseRegNum != Mips::ZERO)
2592 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2593 // And finally, create original instruction with low part
2594 // of offset and new base.
2595 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2597 ? MCOperand::createImm(LoOffset)
2598 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2599 IDLoc, Instructions);
2603 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2604 SmallVectorImpl<MCInst> &Instructions) {
2605 unsigned OpNum = Inst.getNumOperands();
2606 unsigned Opcode = Inst.getOpcode();
2607 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2609 assert (Inst.getOperand(OpNum - 1).isImm() &&
2610 Inst.getOperand(OpNum - 2).isReg() &&
2611 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2613 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2614 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2615 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2616 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2617 // It can be implemented as SWM16 or LWM16 instruction.
2618 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2620 Inst.setOpcode(NewOpcode);
2621 Instructions.push_back(Inst);
2625 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2626 SmallVectorImpl<MCInst> &Instructions) {
2627 bool EmittedNoMacroWarning = false;
2628 unsigned PseudoOpcode = Inst.getOpcode();
2629 unsigned SrcReg = Inst.getOperand(0).getReg();
2630 const MCOperand &TrgOp = Inst.getOperand(1);
2631 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2633 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2634 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2638 TrgReg = TrgOp.getReg();
2639 else if (TrgOp.isImm()) {
2640 warnIfNoMacro(IDLoc);
2641 EmittedNoMacroWarning = true;
2643 TrgReg = getATReg(IDLoc);
2647 switch(PseudoOpcode) {
2649 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2650 case Mips::BLTImmMacro:
2651 PseudoOpcode = Mips::BLT;
2653 case Mips::BLEImmMacro:
2654 PseudoOpcode = Mips::BLE;
2656 case Mips::BGEImmMacro:
2657 PseudoOpcode = Mips::BGE;
2659 case Mips::BGTImmMacro:
2660 PseudoOpcode = Mips::BGT;
2662 case Mips::BLTUImmMacro:
2663 PseudoOpcode = Mips::BLTU;
2665 case Mips::BLEUImmMacro:
2666 PseudoOpcode = Mips::BLEU;
2668 case Mips::BGEUImmMacro:
2669 PseudoOpcode = Mips::BGEU;
2671 case Mips::BGTUImmMacro:
2672 PseudoOpcode = Mips::BGTU;
2674 case Mips::BLTLImmMacro:
2675 PseudoOpcode = Mips::BLTL;
2677 case Mips::BLELImmMacro:
2678 PseudoOpcode = Mips::BLEL;
2680 case Mips::BGELImmMacro:
2681 PseudoOpcode = Mips::BGEL;
2683 case Mips::BGTLImmMacro:
2684 PseudoOpcode = Mips::BGTL;
2686 case Mips::BLTULImmMacro:
2687 PseudoOpcode = Mips::BLTUL;
2689 case Mips::BLEULImmMacro:
2690 PseudoOpcode = Mips::BLEUL;
2692 case Mips::BGEULImmMacro:
2693 PseudoOpcode = Mips::BGEUL;
2695 case Mips::BGTULImmMacro:
2696 PseudoOpcode = Mips::BGTUL;
2700 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2701 false, IDLoc, Instructions))
2705 switch (PseudoOpcode) {
2710 AcceptsEquality = false;
2711 ReverseOrderSLT = false;
2712 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2713 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2714 ZeroSrcOpcode = Mips::BGTZ;
2715 ZeroTrgOpcode = Mips::BLTZ;
2721 AcceptsEquality = true;
2722 ReverseOrderSLT = true;
2723 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2724 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2725 ZeroSrcOpcode = Mips::BGEZ;
2726 ZeroTrgOpcode = Mips::BLEZ;
2732 AcceptsEquality = true;
2733 ReverseOrderSLT = false;
2734 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2735 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2736 ZeroSrcOpcode = Mips::BLEZ;
2737 ZeroTrgOpcode = Mips::BGEZ;
2743 AcceptsEquality = false;
2744 ReverseOrderSLT = true;
2745 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2746 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2747 ZeroSrcOpcode = Mips::BLTZ;
2748 ZeroTrgOpcode = Mips::BGTZ;
2751 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2754 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2755 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2756 if (IsSrcRegZero && IsTrgRegZero) {
2757 // FIXME: All of these Opcode-specific if's are needed for compatibility
2758 // with GAS' behaviour. However, they may not generate the most efficient
2759 // code in some circumstances.
2760 if (PseudoOpcode == Mips::BLT) {
2761 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2765 if (PseudoOpcode == Mips::BLE) {
2766 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2768 Warning(IDLoc, "branch is always taken");
2771 if (PseudoOpcode == Mips::BGE) {
2772 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2774 Warning(IDLoc, "branch is always taken");
2777 if (PseudoOpcode == Mips::BGT) {
2778 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2782 if (PseudoOpcode == Mips::BGTU) {
2783 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2784 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2787 if (AcceptsEquality) {
2788 // If both registers are $0 and the pseudo-branch accepts equality, it
2789 // will always be taken, so we emit an unconditional branch.
2790 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2791 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2792 Warning(IDLoc, "branch is always taken");
2795 // If both registers are $0 and the pseudo-branch does not accept
2796 // equality, it will never be taken, so we don't have to emit anything.
2799 if (IsSrcRegZero || IsTrgRegZero) {
2800 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2801 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2802 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2803 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2804 // the pseudo-branch will never be taken, so we don't emit anything.
2805 // This only applies to unsigned pseudo-branches.
2808 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2809 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2810 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2811 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2812 // the pseudo-branch will always be taken, so we emit an unconditional
2814 // This only applies to unsigned pseudo-branches.
2815 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2816 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2817 Warning(IDLoc, "branch is always taken");
2821 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2822 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2823 // the pseudo-branch will be taken only when the non-zero register is
2824 // different from 0, so we emit a BNEZ.
2826 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2827 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2828 // the pseudo-branch will be taken only when the non-zero register is
2829 // equal to 0, so we emit a BEQZ.
2831 // Because only BLEU and BGEU branch on equality, we can use the
2832 // AcceptsEquality variable to decide when to emit the BEQZ.
2833 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2834 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2835 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2838 // If we have a signed pseudo-branch and one of the registers is $0,
2839 // we can use an appropriate compare-to-zero branch. We select which one
2840 // to use in the switch statement above.
2841 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2842 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2843 IDLoc, Instructions);
2847 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2848 // expansions. If it is not available, we return.
2849 unsigned ATRegNum = getATReg(IDLoc);
2853 if (!EmittedNoMacroWarning)
2854 warnIfNoMacro(IDLoc);
2856 // SLT fits well with 2 of our 4 pseudo-branches:
2857 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2858 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2859 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2860 // This is accomplished by using a BNEZ with the result of the SLT.
2862 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2863 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2864 // Because only BGE and BLE branch on equality, we can use the
2865 // AcceptsEquality variable to decide when to emit the BEQZ.
2866 // Note that the order of the SLT arguments doesn't change between
2869 // The same applies to the unsigned variants, except that SLTu is used
2871 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2872 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2873 IDLoc, Instructions);
2875 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2876 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2877 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2882 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2883 SmallVectorImpl<MCInst> &Instructions,
2884 const bool IsMips64, const bool Signed) {
2885 if (hasMips32r6()) {
2886 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2890 warnIfNoMacro(IDLoc);
2892 const MCOperand &RsRegOp = Inst.getOperand(0);
2893 assert(RsRegOp.isReg() && "expected register operand kind");
2894 unsigned RsReg = RsRegOp.getReg();
2896 const MCOperand &RtRegOp = Inst.getOperand(1);
2897 assert(RtRegOp.isReg() && "expected register operand kind");
2898 unsigned RtReg = RtRegOp.getReg();
2903 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2904 ZeroReg = Mips::ZERO_64;
2906 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2907 ZeroReg = Mips::ZERO;
2910 bool UseTraps = useTraps();
2912 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2913 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2914 Warning(IDLoc, "dividing zero by zero");
2916 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2918 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2922 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2926 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2931 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2932 Warning(IDLoc, "division by zero");
2935 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2939 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2944 // FIXME: The values for these two BranchTarget variables may be different in
2945 // micromips. These magic numbers need to be removed.
2946 unsigned BranchTargetNoTraps;
2947 unsigned BranchTarget;
2950 BranchTarget = IsMips64 ? 12 : 8;
2951 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2953 BranchTarget = IsMips64 ? 20 : 16;
2954 BranchTargetNoTraps = 8;
2955 // Branch to the li instruction.
2956 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2960 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2963 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2966 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2970 unsigned ATReg = getATReg(IDLoc);
2974 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2976 // Branch to the mflo instruction.
2977 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2978 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2979 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2981 // Branch to the mflo instruction.
2982 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2983 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2987 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2989 // Branch to the mflo instruction.
2990 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2991 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2992 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2994 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2998 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
2999 SmallVectorImpl<MCInst> &Instructions) {
3000 if (hasMips32r6() || hasMips64r6()) {
3001 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3005 warnIfNoMacro(IDLoc);
3007 const MCOperand &DstRegOp = Inst.getOperand(0);
3008 assert(DstRegOp.isReg() && "expected register operand kind");
3010 const MCOperand &SrcRegOp = Inst.getOperand(1);
3011 assert(SrcRegOp.isReg() && "expected register operand kind");
3013 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3014 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3016 unsigned DstReg = DstRegOp.getReg();
3017 unsigned SrcReg = SrcRegOp.getReg();
3018 int64_t OffsetValue = OffsetImmOp.getImm();
3020 // NOTE: We always need AT for ULHU, as it is always used as the source
3021 // register for one of the LBu's.
3022 unsigned ATReg = getATReg(IDLoc);
3026 // When the value of offset+1 does not fit in 16 bits, we have to load the
3027 // offset in AT, (D)ADDu the original source register (if there was one), and
3028 // then use AT as the source register for the 2 generated LBu's.
3029 bool LoadedOffsetInAT = false;
3030 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3031 LoadedOffsetInAT = true;
3033 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3034 true, IDLoc, Instructions))
3037 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3038 // because it will make our output more similar to GAS'. For example,
3039 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3040 // instead of just an "ori $1, $9, 32768".
3041 // NOTE: If there is no source register specified in the ULHU, the parser
3042 // will interpret it as $0.
3043 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3044 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3047 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3048 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3049 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3051 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3053 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3054 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3056 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3057 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3060 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3062 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3063 FirstLbuOffset, IDLoc, Instructions);
3065 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3068 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3070 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3075 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3076 SmallVectorImpl<MCInst> &Instructions) {
3077 if (hasMips32r6() || hasMips64r6()) {
3078 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3082 const MCOperand &DstRegOp = Inst.getOperand(0);
3083 assert(DstRegOp.isReg() && "expected register operand kind");
3085 const MCOperand &SrcRegOp = Inst.getOperand(1);
3086 assert(SrcRegOp.isReg() && "expected register operand kind");
3088 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3089 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3091 unsigned SrcReg = SrcRegOp.getReg();
3092 int64_t OffsetValue = OffsetImmOp.getImm();
3095 // When the value of offset+3 does not fit in 16 bits, we have to load the
3096 // offset in AT, (D)ADDu the original source register (if there was one), and
3097 // then use AT as the source register for the generated LWL and LWR.
3098 bool LoadedOffsetInAT = false;
3099 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3100 ATReg = getATReg(IDLoc);
3103 LoadedOffsetInAT = true;
3105 warnIfNoMacro(IDLoc);
3107 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3108 true, IDLoc, Instructions))
3111 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3112 // because it will make our output more similar to GAS'. For example,
3113 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3114 // instead of just an "ori $1, $9, 32768".
3115 // NOTE: If there is no source register specified in the ULW, the parser
3116 // will interpret it as $0.
3117 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3118 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3121 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3122 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3124 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3125 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3127 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3128 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3131 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3134 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3140 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3141 SmallVectorImpl<MCInst> &Instructions) {
3143 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3144 assert (Inst.getOperand(0).isReg() &&
3145 Inst.getOperand(1).isReg() &&
3146 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3148 unsigned ATReg = Mips::NoRegister;
3149 unsigned FinalDstReg = Mips::NoRegister;
3150 unsigned DstReg = Inst.getOperand(0).getReg();
3151 unsigned SrcReg = Inst.getOperand(1).getReg();
3152 int64_t ImmValue = Inst.getOperand(2).getImm();
3154 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3156 unsigned FinalOpcode = Inst.getOpcode();
3158 if (DstReg == SrcReg) {
3159 ATReg = getATReg(Inst.getLoc());
3162 FinalDstReg = DstReg;
3166 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3167 switch (FinalOpcode) {
3169 llvm_unreachable("unimplemented expansion");
3171 FinalOpcode = Mips::ADD;
3174 FinalOpcode = Mips::ADDu;
3177 FinalOpcode = Mips::AND;
3179 case (Mips::NORImm):
3180 FinalOpcode = Mips::NOR;
3183 FinalOpcode = Mips::OR;
3186 FinalOpcode = Mips::SLT;
3189 FinalOpcode = Mips::SLTu;
3192 FinalOpcode = Mips::XOR;
3196 if (FinalDstReg == Mips::NoRegister)
3197 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3199 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3206 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3207 SmallVectorImpl<MCInst> &Instructions) {
3208 if (hasShortDelaySlot)
3209 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3211 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3214 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3215 unsigned TrgReg, bool Is64Bit,
3216 SmallVectorImpl<MCInst> &Instructions) {
3217 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3221 void MipsAsmParser::createCpRestoreMemOp(
3222 bool IsLoad, int StackOffset, SMLoc IDLoc,
3223 SmallVectorImpl<MCInst> &Instructions) {
3224 // If the offset can not fit into 16 bits, we need to expand.
3225 if (!isInt<16>(StackOffset)) {
3227 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3228 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3229 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3230 MemInst.addOperand(MCOperand::createImm(StackOffset));
3231 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3235 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3239 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3240 // As described by the Mips32r2 spec, the registers Rd and Rs for
3241 // jalr.hb must be different.
3242 unsigned Opcode = Inst.getOpcode();
3244 if (Opcode == Mips::JALR_HB &&
3245 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3246 return Match_RequiresDifferentSrcAndDst;
3248 return Match_Success;
3251 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3252 uint64_t ErrorInfo) {
3253 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3254 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3255 if (ErrorLoc == SMLoc())
3262 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3263 OperandVector &Operands,
3265 uint64_t &ErrorInfo,
3266 bool MatchingInlineAsm) {
3269 SmallVector<MCInst, 8> Instructions;
3270 unsigned MatchResult =
3271 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3273 switch (MatchResult) {
3274 case Match_Success: {
3275 if (processInstruction(Inst, IDLoc, Instructions))
3277 for (unsigned i = 0; i < Instructions.size(); i++)
3278 Out.EmitInstruction(Instructions[i], STI);
3281 case Match_MissingFeature:
3282 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3284 case Match_InvalidOperand: {
3285 SMLoc ErrorLoc = IDLoc;
3286 if (ErrorInfo != ~0ULL) {
3287 if (ErrorInfo >= Operands.size())
3288 return Error(IDLoc, "too few operands for instruction");
3290 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3291 if (ErrorLoc == SMLoc())
3295 return Error(ErrorLoc, "invalid operand for instruction");
3297 case Match_MnemonicFail:
3298 return Error(IDLoc, "invalid instruction");
3299 case Match_RequiresDifferentSrcAndDst:
3300 return Error(IDLoc, "source and destination must be different");
3302 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3304 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3305 "expected 2-bit unsigned immediate");
3307 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3308 "expected immediate in range 1 .. 4");
3311 llvm_unreachable("Implement any new match types added!");
3314 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3315 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3316 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3317 ") without \".set noat\"");
3320 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3321 if (!AssemblerOptions.back()->isMacro())
3322 Warning(Loc, "macro instruction expanded into multiple instructions");
3326 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3327 SMRange Range, bool ShowColors) {
3328 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3329 Range, SMFixIt(Range, FixMsg),
3333 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3336 CC = StringSwitch<unsigned>(Name)
3372 if (!(isABI_N32() || isABI_N64()))
3375 if (12 <= CC && CC <= 15) {
3376 // Name is one of t4-t7
3377 AsmToken RegTok = getLexer().peekTok();
3378 SMRange RegRange = RegTok.getLocRange();
3380 StringRef FixedName = StringSwitch<StringRef>(Name)
3386 assert(FixedName != "" && "Register name is not one of t4-t7.");
3388 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3389 "Did you mean $" + FixedName + "?", RegRange);
3392 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3393 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3394 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3395 if (8 <= CC && CC <= 11)
3399 CC = StringSwitch<unsigned>(Name)
3411 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3414 CC = StringSwitch<unsigned>(Name)
3415 .Case("hwr_cpunum", 0)
3416 .Case("hwr_synci_step", 1)
3418 .Case("hwr_ccres", 3)
3419 .Case("hwr_ulr", 29)
3425 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3427 if (Name[0] == 'f') {
3428 StringRef NumString = Name.substr(1);
3430 if (NumString.getAsInteger(10, IntVal))
3431 return -1; // This is not an integer.
3432 if (IntVal > 31) // Maximum index for fpu register.
3439 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3441 if (Name.startswith("fcc")) {
3442 StringRef NumString = Name.substr(3);
3444 if (NumString.getAsInteger(10, IntVal))
3445 return -1; // This is not an integer.
3446 if (IntVal > 7) // There are only 8 fcc registers.
3453 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3455 if (Name.startswith("ac")) {
3456 StringRef NumString = Name.substr(2);
3458 if (NumString.getAsInteger(10, IntVal))
3459 return -1; // This is not an integer.
3460 if (IntVal > 3) // There are only 3 acc registers.
3467 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3470 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3479 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3482 CC = StringSwitch<unsigned>(Name)
3485 .Case("msaaccess", 2)
3487 .Case("msamodify", 4)
3488 .Case("msarequest", 5)
3490 .Case("msaunmap", 7)
3496 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3497 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3499 reportParseError(Loc,
3500 "pseudo-instruction requires $at, which is not available");
3503 unsigned AT = getReg(
3504 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3508 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3509 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3512 unsigned MipsAsmParser::getGPR(int RegNo) {
3513 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3517 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3519 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3522 return getReg(RegClass, RegNum);
3525 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3526 MCAsmParser &Parser = getParser();
3527 DEBUG(dbgs() << "parseOperand\n");
3529 // Check if the current operand has a custom associated parser, if so, try to
3530 // custom parse the operand, or fallback to the general approach.
3531 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3532 if (ResTy == MatchOperand_Success)
3534 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3535 // there was a match, but an error occurred, in which case, just return that
3536 // the operand parsing failed.
3537 if (ResTy == MatchOperand_ParseFail)
3540 DEBUG(dbgs() << ".. Generic Parser\n");
3542 switch (getLexer().getKind()) {
3544 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3546 case AsmToken::Dollar: {
3547 // Parse the register.
3548 SMLoc S = Parser.getTok().getLoc();
3550 // Almost all registers have been parsed by custom parsers. There is only
3551 // one exception to this. $zero (and it's alias $0) will reach this point
3552 // for div, divu, and similar instructions because it is not an operand
3553 // to the instruction definition but an explicit register. Special case
3554 // this situation for now.
3555 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3558 // Maybe it is a symbol reference.
3559 StringRef Identifier;
3560 if (Parser.parseIdentifier(Identifier))
3563 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3564 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3565 // Otherwise create a symbol reference.
3567 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3569 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3572 // Else drop to expression parsing.
3573 case AsmToken::LParen:
3574 case AsmToken::Minus:
3575 case AsmToken::Plus:
3576 case AsmToken::Integer:
3577 case AsmToken::Tilde:
3578 case AsmToken::String: {
3579 DEBUG(dbgs() << ".. generic integer\n");
3580 OperandMatchResultTy ResTy = parseImm(Operands);
3581 return ResTy != MatchOperand_Success;
3583 case AsmToken::Percent: {
3584 // It is a symbol reference or constant expression.
3585 const MCExpr *IdVal;
3586 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3587 if (parseRelocOperand(IdVal))
3590 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3592 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3594 } // case AsmToken::Percent
3595 } // switch(getLexer().getKind())
3599 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3600 StringRef RelocStr) {
3602 // Check the type of the expression.
3603 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3604 // It's a constant, evaluate reloc value.
3606 switch (getVariantKind(RelocStr)) {
3607 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3608 // Get the 1st 16-bits.
3609 Val = MCE->getValue() & 0xffff;
3611 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3612 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3613 // 16 bits being negative.
3614 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3616 case MCSymbolRefExpr::VK_Mips_HIGHER:
3617 // Get the 3rd 16-bits.
3618 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3620 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3621 // Get the 4th 16-bits.
3622 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3625 report_fatal_error("unsupported reloc value");
3627 return MCConstantExpr::create(Val, getContext());
3630 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3631 // It's a symbol, create a symbolic expression from the symbol.
3632 const MCSymbol *Symbol = &MSRE->getSymbol();
3633 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3634 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3638 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3639 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3641 // Try to create target expression.
3642 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3643 return MipsMCExpr::create(VK, Expr, getContext());
3645 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3646 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3647 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3651 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3652 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3653 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3656 // Just return the original expression.
3660 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3662 switch (Expr->getKind()) {
3663 case MCExpr::Constant:
3665 case MCExpr::SymbolRef:
3666 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3667 case MCExpr::Binary:
3668 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3669 if (!isEvaluated(BE->getLHS()))
3671 return isEvaluated(BE->getRHS());
3674 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3675 case MCExpr::Target:
3681 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3682 MCAsmParser &Parser = getParser();
3683 Parser.Lex(); // Eat the % token.
3684 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3685 if (Tok.isNot(AsmToken::Identifier))
3688 std::string Str = Tok.getIdentifier();
3690 Parser.Lex(); // Eat the identifier.
3691 // Now make an expression from the rest of the operand.
3692 const MCExpr *IdVal;
3695 if (getLexer().getKind() == AsmToken::LParen) {
3697 Parser.Lex(); // Eat the '(' token.
3698 if (getLexer().getKind() == AsmToken::Percent) {
3699 Parser.Lex(); // Eat the % token.
3700 const AsmToken &nextTok = Parser.getTok();
3701 if (nextTok.isNot(AsmToken::Identifier))
3704 Str += nextTok.getIdentifier();
3705 Parser.Lex(); // Eat the identifier.
3706 if (getLexer().getKind() != AsmToken::LParen)
3711 if (getParser().parseParenExpression(IdVal, EndLoc))
3714 while (getLexer().getKind() == AsmToken::RParen)
3715 Parser.Lex(); // Eat the ')' token.
3718 return true; // Parenthesis must follow the relocation operand.
3720 Res = evaluateRelocExpr(IdVal, Str);
3724 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3726 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3727 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3728 if (ResTy == MatchOperand_Success) {
3729 assert(Operands.size() == 1);
3730 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3731 StartLoc = Operand.getStartLoc();
3732 EndLoc = Operand.getEndLoc();
3734 // AFAIK, we only support numeric registers and named GPR's in CFI
3736 // Don't worry about eating tokens before failing. Using an unrecognised
3737 // register is a parse error.
3738 if (Operand.isGPRAsmReg()) {
3739 // Resolve to GPR32 or GPR64 appropriately.
3740 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3743 return (RegNo == (unsigned)-1);
3746 assert(Operands.size() == 0);
3747 return (RegNo == (unsigned)-1);
3750 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3751 MCAsmParser &Parser = getParser();
3754 unsigned NumOfLParen = 0;
3756 while (getLexer().getKind() == AsmToken::LParen) {
3761 switch (getLexer().getKind()) {
3764 case AsmToken::Identifier:
3765 case AsmToken::LParen:
3766 case AsmToken::Integer:
3767 case AsmToken::Minus:
3768 case AsmToken::Plus:
3770 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3772 Result = (getParser().parseExpression(Res));
3773 while (getLexer().getKind() == AsmToken::RParen)
3776 case AsmToken::Percent:
3777 Result = parseRelocOperand(Res);
3782 MipsAsmParser::OperandMatchResultTy
3783 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3784 MCAsmParser &Parser = getParser();
3785 DEBUG(dbgs() << "parseMemOperand\n");
3786 const MCExpr *IdVal = nullptr;
3788 bool isParenExpr = false;
3789 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3790 // First operand is the offset.
3791 S = Parser.getTok().getLoc();
3793 if (getLexer().getKind() == AsmToken::LParen) {
3798 if (getLexer().getKind() != AsmToken::Dollar) {
3799 if (parseMemOffset(IdVal, isParenExpr))
3800 return MatchOperand_ParseFail;
3802 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3803 if (Tok.isNot(AsmToken::LParen)) {
3804 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3805 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3807 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3808 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3809 return MatchOperand_Success;
3811 if (Tok.is(AsmToken::EndOfStatement)) {
3813 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3815 // Zero register assumed, add a memory operand with ZERO as its base.
3816 // "Base" will be managed by k_Memory.
3817 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3820 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3821 return MatchOperand_Success;
3823 Error(Parser.getTok().getLoc(), "'(' expected");
3824 return MatchOperand_ParseFail;
3827 Parser.Lex(); // Eat the '(' token.
3830 Res = parseAnyRegister(Operands);
3831 if (Res != MatchOperand_Success)
3834 if (Parser.getTok().isNot(AsmToken::RParen)) {
3835 Error(Parser.getTok().getLoc(), "')' expected");
3836 return MatchOperand_ParseFail;
3839 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3841 Parser.Lex(); // Eat the ')' token.
3844 IdVal = MCConstantExpr::create(0, getContext());
3846 // Replace the register operand with the memory operand.
3847 std::unique_ptr<MipsOperand> op(
3848 static_cast<MipsOperand *>(Operands.back().release()));
3849 // Remove the register from the operands.
3850 // "op" will be managed by k_Memory.
3851 Operands.pop_back();
3852 // Add the memory operand.
3853 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3855 if (IdVal->evaluateAsAbsolute(Imm))
3856 IdVal = MCConstantExpr::create(Imm, getContext());
3857 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3858 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3862 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3863 return MatchOperand_Success;
3866 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3867 MCAsmParser &Parser = getParser();
3868 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3870 SMLoc S = Parser.getTok().getLoc();
3872 if (Sym->isVariable())
3873 Expr = Sym->getVariableValue();
3876 if (Expr->getKind() == MCExpr::SymbolRef) {
3877 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3878 StringRef DefSymbol = Ref->getSymbol().getName();
3879 if (DefSymbol.startswith("$")) {
3880 OperandMatchResultTy ResTy =
3881 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3882 if (ResTy == MatchOperand_Success) {
3885 } else if (ResTy == MatchOperand_ParseFail)
3886 llvm_unreachable("Should never ParseFail");
3889 } else if (Expr->getKind() == MCExpr::Constant) {
3891 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3893 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3900 MipsAsmParser::OperandMatchResultTy
3901 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3902 StringRef Identifier,
3904 int Index = matchCPURegisterName(Identifier);
3906 Operands.push_back(MipsOperand::createGPRReg(
3907 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3908 return MatchOperand_Success;
3911 Index = matchHWRegsRegisterName(Identifier);
3913 Operands.push_back(MipsOperand::createHWRegsReg(
3914 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3915 return MatchOperand_Success;
3918 Index = matchFPURegisterName(Identifier);
3920 Operands.push_back(MipsOperand::createFGRReg(
3921 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3922 return MatchOperand_Success;
3925 Index = matchFCCRegisterName(Identifier);
3927 Operands.push_back(MipsOperand::createFCCReg(
3928 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3929 return MatchOperand_Success;
3932 Index = matchACRegisterName(Identifier);
3934 Operands.push_back(MipsOperand::createACCReg(
3935 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3936 return MatchOperand_Success;
3939 Index = matchMSA128RegisterName(Identifier);
3941 Operands.push_back(MipsOperand::createMSA128Reg(
3942 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3943 return MatchOperand_Success;
3946 Index = matchMSA128CtrlRegisterName(Identifier);
3948 Operands.push_back(MipsOperand::createMSACtrlReg(
3949 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3950 return MatchOperand_Success;
3953 return MatchOperand_NoMatch;
3956 MipsAsmParser::OperandMatchResultTy
3957 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3958 MCAsmParser &Parser = getParser();
3959 auto Token = Parser.getLexer().peekTok(false);
3961 if (Token.is(AsmToken::Identifier)) {
3962 DEBUG(dbgs() << ".. identifier\n");
3963 StringRef Identifier = Token.getIdentifier();
3964 OperandMatchResultTy ResTy =
3965 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3967 } else if (Token.is(AsmToken::Integer)) {
3968 DEBUG(dbgs() << ".. integer\n");
3969 Operands.push_back(MipsOperand::createNumericReg(
3970 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3972 return MatchOperand_Success;
3975 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3977 return MatchOperand_NoMatch;
3980 MipsAsmParser::OperandMatchResultTy
3981 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3982 MCAsmParser &Parser = getParser();
3983 DEBUG(dbgs() << "parseAnyRegister\n");
3985 auto Token = Parser.getTok();
3987 SMLoc S = Token.getLoc();
3989 if (Token.isNot(AsmToken::Dollar)) {
3990 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3991 if (Token.is(AsmToken::Identifier)) {
3992 if (searchSymbolAlias(Operands))
3993 return MatchOperand_Success;
3995 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3996 return MatchOperand_NoMatch;
3998 DEBUG(dbgs() << ".. $\n");
4000 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4001 if (ResTy == MatchOperand_Success) {
4003 Parser.Lex(); // identifier
4008 MipsAsmParser::OperandMatchResultTy
4009 MipsAsmParser::parseImm(OperandVector &Operands) {
4010 MCAsmParser &Parser = getParser();
4011 switch (getLexer().getKind()) {
4013 return MatchOperand_NoMatch;
4014 case AsmToken::LParen:
4015 case AsmToken::Minus:
4016 case AsmToken::Plus:
4017 case AsmToken::Integer:
4018 case AsmToken::Tilde:
4019 case AsmToken::String:
4023 const MCExpr *IdVal;
4024 SMLoc S = Parser.getTok().getLoc();
4025 if (getParser().parseExpression(IdVal))
4026 return MatchOperand_ParseFail;
4028 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4029 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4030 return MatchOperand_Success;
4033 MipsAsmParser::OperandMatchResultTy
4034 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4035 MCAsmParser &Parser = getParser();
4036 DEBUG(dbgs() << "parseJumpTarget\n");
4038 SMLoc S = getLexer().getLoc();
4040 // Integers and expressions are acceptable
4041 OperandMatchResultTy ResTy = parseImm(Operands);
4042 if (ResTy != MatchOperand_NoMatch)
4045 // Registers are a valid target and have priority over symbols.
4046 ResTy = parseAnyRegister(Operands);
4047 if (ResTy != MatchOperand_NoMatch)
4050 const MCExpr *Expr = nullptr;
4051 if (Parser.parseExpression(Expr)) {
4052 // We have no way of knowing if a symbol was consumed so we must ParseFail
4053 return MatchOperand_ParseFail;
4056 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4057 return MatchOperand_Success;
4060 MipsAsmParser::OperandMatchResultTy
4061 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4062 MCAsmParser &Parser = getParser();
4063 const MCExpr *IdVal;
4064 // If the first token is '$' we may have register operand.
4065 if (Parser.getTok().is(AsmToken::Dollar))
4066 return MatchOperand_NoMatch;
4067 SMLoc S = Parser.getTok().getLoc();
4068 if (getParser().parseExpression(IdVal))
4069 return MatchOperand_ParseFail;
4070 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4071 assert(MCE && "Unexpected MCExpr type.");
4072 int64_t Val = MCE->getValue();
4073 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4074 Operands.push_back(MipsOperand::CreateImm(
4075 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4076 return MatchOperand_Success;
4079 MipsAsmParser::OperandMatchResultTy
4080 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4081 MCAsmParser &Parser = getParser();
4082 switch (getLexer().getKind()) {
4084 return MatchOperand_NoMatch;
4085 case AsmToken::LParen:
4086 case AsmToken::Plus:
4087 case AsmToken::Minus:
4088 case AsmToken::Integer:
4093 SMLoc S = Parser.getTok().getLoc();
4095 if (getParser().parseExpression(Expr))
4096 return MatchOperand_ParseFail;
4099 if (!Expr->evaluateAsAbsolute(Val)) {
4100 Error(S, "expected immediate value");
4101 return MatchOperand_ParseFail;
4104 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4105 // and because the CPU always adds one to the immediate field, the allowed
4106 // range becomes 1..4. We'll only check the range here and will deal
4107 // with the addition/subtraction when actually decoding/encoding
4109 if (Val < 1 || Val > 4) {
4110 Error(S, "immediate not in range (1..4)");
4111 return MatchOperand_ParseFail;
4115 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4116 return MatchOperand_Success;
4119 MipsAsmParser::OperandMatchResultTy
4120 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4121 MCAsmParser &Parser = getParser();
4122 SmallVector<unsigned, 10> Regs;
4124 unsigned PrevReg = Mips::NoRegister;
4125 bool RegRange = false;
4126 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4128 if (Parser.getTok().isNot(AsmToken::Dollar))
4129 return MatchOperand_ParseFail;
4131 SMLoc S = Parser.getTok().getLoc();
4132 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4133 SMLoc E = getLexer().getLoc();
4134 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4135 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4137 // Remove last register operand because registers from register range
4138 // should be inserted first.
4139 if (RegNo == Mips::RA) {
4140 Regs.push_back(RegNo);
4142 unsigned TmpReg = PrevReg + 1;
4143 while (TmpReg <= RegNo) {
4144 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4145 Error(E, "invalid register operand");
4146 return MatchOperand_ParseFail;
4150 Regs.push_back(TmpReg++);
4156 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4157 (RegNo != Mips::RA)) {
4158 Error(E, "$16 or $31 expected");
4159 return MatchOperand_ParseFail;
4160 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4161 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4162 Error(E, "invalid register operand");
4163 return MatchOperand_ParseFail;
4164 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4165 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4166 Error(E, "consecutive register numbers expected");
4167 return MatchOperand_ParseFail;
4170 Regs.push_back(RegNo);
4173 if (Parser.getTok().is(AsmToken::Minus))
4176 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4177 !Parser.getTok().isNot(AsmToken::Comma)) {
4178 Error(E, "',' or '-' expected");
4179 return MatchOperand_ParseFail;
4182 Lex(); // Consume comma or minus
4183 if (Parser.getTok().isNot(AsmToken::Dollar))
4189 SMLoc E = Parser.getTok().getLoc();
4190 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4191 parseMemOperand(Operands);
4192 return MatchOperand_Success;
4195 MipsAsmParser::OperandMatchResultTy
4196 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4197 MCAsmParser &Parser = getParser();
4199 SMLoc S = Parser.getTok().getLoc();
4200 if (parseAnyRegister(Operands) != MatchOperand_Success)
4201 return MatchOperand_ParseFail;
4203 SMLoc E = Parser.getTok().getLoc();
4204 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4205 unsigned Reg = Op.getGPR32Reg();
4206 Operands.pop_back();
4207 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4208 return MatchOperand_Success;
4211 MipsAsmParser::OperandMatchResultTy
4212 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4213 MCAsmParser &Parser = getParser();
4214 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4215 SmallVector<unsigned, 10> Regs;
4217 if (Parser.getTok().isNot(AsmToken::Dollar))
4218 return MatchOperand_ParseFail;
4220 SMLoc S = Parser.getTok().getLoc();
4222 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4223 return MatchOperand_ParseFail;
4225 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4226 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4227 Regs.push_back(RegNo);
4229 SMLoc E = Parser.getTok().getLoc();
4230 if (Parser.getTok().isNot(AsmToken::Comma)) {
4231 Error(E, "',' expected");
4232 return MatchOperand_ParseFail;
4238 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4239 return MatchOperand_ParseFail;
4241 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4242 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4243 Regs.push_back(RegNo);
4245 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4247 return MatchOperand_Success;
4250 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4252 MCSymbolRefExpr::VariantKind VK =
4253 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4254 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4255 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4256 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4257 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4258 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4259 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4260 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4261 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4262 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4263 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4264 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4265 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4266 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4267 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4268 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4269 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4270 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4271 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4272 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4273 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4274 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4275 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4276 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4277 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4278 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4279 .Default(MCSymbolRefExpr::VK_None);
4281 assert(VK != MCSymbolRefExpr::VK_None);
4286 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4288 /// ::= '(', register, ')'
4289 /// handle it before we iterate so we don't get tripped up by the lack of
4291 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4292 MCAsmParser &Parser = getParser();
4293 if (getLexer().is(AsmToken::LParen)) {
4295 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4297 if (parseOperand(Operands, Name)) {
4298 SMLoc Loc = getLexer().getLoc();
4299 Parser.eatToEndOfStatement();
4300 return Error(Loc, "unexpected token in argument list");
4302 if (Parser.getTok().isNot(AsmToken::RParen)) {
4303 SMLoc Loc = getLexer().getLoc();
4304 Parser.eatToEndOfStatement();
4305 return Error(Loc, "unexpected token, expected ')'");
4308 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4314 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4315 /// either one of these.
4316 /// ::= '[', register, ']'
4317 /// ::= '[', integer, ']'
4318 /// handle it before we iterate so we don't get tripped up by the lack of
4320 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4321 OperandVector &Operands) {
4322 MCAsmParser &Parser = getParser();
4323 if (getLexer().is(AsmToken::LBrac)) {
4325 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4327 if (parseOperand(Operands, Name)) {
4328 SMLoc Loc = getLexer().getLoc();
4329 Parser.eatToEndOfStatement();
4330 return Error(Loc, "unexpected token in argument list");
4332 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4333 SMLoc Loc = getLexer().getLoc();
4334 Parser.eatToEndOfStatement();
4335 return Error(Loc, "unexpected token, expected ']'");
4338 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4344 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4345 SMLoc NameLoc, OperandVector &Operands) {
4346 MCAsmParser &Parser = getParser();
4347 DEBUG(dbgs() << "ParseInstruction\n");
4349 // We have reached first instruction, module directive are now forbidden.
4350 getTargetStreamer().forbidModuleDirective();
4352 // Check if we have valid mnemonic
4353 if (!mnemonicIsValid(Name, 0)) {
4354 Parser.eatToEndOfStatement();
4355 return Error(NameLoc, "unknown instruction");
4357 // First operand in MCInst is instruction mnemonic.
4358 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4360 // Read the remaining operands.
4361 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4362 // Read the first operand.
4363 if (parseOperand(Operands, Name)) {
4364 SMLoc Loc = getLexer().getLoc();
4365 Parser.eatToEndOfStatement();
4366 return Error(Loc, "unexpected token in argument list");
4368 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4370 // AFAIK, parenthesis suffixes are never on the first operand
4372 while (getLexer().is(AsmToken::Comma)) {
4373 Parser.Lex(); // Eat the comma.
4374 // Parse and remember the operand.
4375 if (parseOperand(Operands, Name)) {
4376 SMLoc Loc = getLexer().getLoc();
4377 Parser.eatToEndOfStatement();
4378 return Error(Loc, "unexpected token in argument list");
4380 // Parse bracket and parenthesis suffixes before we iterate
4381 if (getLexer().is(AsmToken::LBrac)) {
4382 if (parseBracketSuffix(Name, Operands))
4384 } else if (getLexer().is(AsmToken::LParen) &&
4385 parseParenSuffix(Name, Operands))
4389 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4390 SMLoc Loc = getLexer().getLoc();
4391 Parser.eatToEndOfStatement();
4392 return Error(Loc, "unexpected token in argument list");
4394 Parser.Lex(); // Consume the EndOfStatement.
4398 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4399 MCAsmParser &Parser = getParser();
4400 SMLoc Loc = getLexer().getLoc();
4401 Parser.eatToEndOfStatement();
4402 return Error(Loc, ErrorMsg);
4405 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4406 return Error(Loc, ErrorMsg);
4409 bool MipsAsmParser::parseSetNoAtDirective() {
4410 MCAsmParser &Parser = getParser();
4411 // Line should look like: ".set noat".
4413 // Set the $at register to $0.
4414 AssemblerOptions.back()->setATRegIndex(0);
4416 Parser.Lex(); // Eat "noat".
4418 // If this is not the end of the statement, report an error.
4419 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4420 reportParseError("unexpected token, expected end of statement");
4424 getTargetStreamer().emitDirectiveSetNoAt();
4425 Parser.Lex(); // Consume the EndOfStatement.
4429 bool MipsAsmParser::parseSetAtDirective() {
4430 // Line can be: ".set at", which sets $at to $1
4431 // or ".set at=$reg", which sets $at to $reg.
4432 MCAsmParser &Parser = getParser();
4433 Parser.Lex(); // Eat "at".
4435 if (getLexer().is(AsmToken::EndOfStatement)) {
4436 // No register was specified, so we set $at to $1.
4437 AssemblerOptions.back()->setATRegIndex(1);
4439 getTargetStreamer().emitDirectiveSetAt();
4440 Parser.Lex(); // Consume the EndOfStatement.
4444 if (getLexer().isNot(AsmToken::Equal)) {
4445 reportParseError("unexpected token, expected equals sign");
4448 Parser.Lex(); // Eat "=".
4450 if (getLexer().isNot(AsmToken::Dollar)) {
4451 if (getLexer().is(AsmToken::EndOfStatement)) {
4452 reportParseError("no register specified");
4455 reportParseError("unexpected token, expected dollar sign '$'");
4459 Parser.Lex(); // Eat "$".
4461 // Find out what "reg" is.
4463 const AsmToken &Reg = Parser.getTok();
4464 if (Reg.is(AsmToken::Identifier)) {
4465 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4466 } else if (Reg.is(AsmToken::Integer)) {
4467 AtRegNo = Reg.getIntVal();
4469 reportParseError("unexpected token, expected identifier or integer");
4473 // Check if $reg is a valid register. If it is, set $at to $reg.
4474 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4475 reportParseError("invalid register");
4478 Parser.Lex(); // Eat "reg".
4480 // If this is not the end of the statement, report an error.
4481 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4482 reportParseError("unexpected token, expected end of statement");
4486 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4488 Parser.Lex(); // Consume the EndOfStatement.
4492 bool MipsAsmParser::parseSetReorderDirective() {
4493 MCAsmParser &Parser = getParser();
4495 // If this is not the end of the statement, report an error.
4496 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4497 reportParseError("unexpected token, expected end of statement");
4500 AssemblerOptions.back()->setReorder();
4501 getTargetStreamer().emitDirectiveSetReorder();
4502 Parser.Lex(); // Consume the EndOfStatement.
4506 bool MipsAsmParser::parseSetNoReorderDirective() {
4507 MCAsmParser &Parser = getParser();
4509 // If this is not the end of the statement, report an error.
4510 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4511 reportParseError("unexpected token, expected end of statement");
4514 AssemblerOptions.back()->setNoReorder();
4515 getTargetStreamer().emitDirectiveSetNoReorder();
4516 Parser.Lex(); // Consume the EndOfStatement.
4520 bool MipsAsmParser::parseSetMacroDirective() {
4521 MCAsmParser &Parser = getParser();
4523 // If this is not the end of the statement, report an error.
4524 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4525 reportParseError("unexpected token, expected end of statement");
4528 AssemblerOptions.back()->setMacro();
4529 getTargetStreamer().emitDirectiveSetMacro();
4530 Parser.Lex(); // Consume the EndOfStatement.
4534 bool MipsAsmParser::parseSetNoMacroDirective() {
4535 MCAsmParser &Parser = getParser();
4537 // If this is not the end of the statement, report an error.
4538 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4539 reportParseError("unexpected token, expected end of statement");
4542 if (AssemblerOptions.back()->isReorder()) {
4543 reportParseError("`noreorder' must be set before `nomacro'");
4546 AssemblerOptions.back()->setNoMacro();
4547 getTargetStreamer().emitDirectiveSetNoMacro();
4548 Parser.Lex(); // Consume the EndOfStatement.
4552 bool MipsAsmParser::parseSetMsaDirective() {
4553 MCAsmParser &Parser = getParser();
4556 // If this is not the end of the statement, report an error.
4557 if (getLexer().isNot(AsmToken::EndOfStatement))
4558 return reportParseError("unexpected token, expected end of statement");
4560 setFeatureBits(Mips::FeatureMSA, "msa");
4561 getTargetStreamer().emitDirectiveSetMsa();
4565 bool MipsAsmParser::parseSetNoMsaDirective() {
4566 MCAsmParser &Parser = getParser();
4569 // If this is not the end of the statement, report an error.
4570 if (getLexer().isNot(AsmToken::EndOfStatement))
4571 return reportParseError("unexpected token, expected end of statement");
4573 clearFeatureBits(Mips::FeatureMSA, "msa");
4574 getTargetStreamer().emitDirectiveSetNoMsa();
4578 bool MipsAsmParser::parseSetNoDspDirective() {
4579 MCAsmParser &Parser = getParser();
4580 Parser.Lex(); // Eat "nodsp".
4582 // If this is not the end of the statement, report an error.
4583 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4584 reportParseError("unexpected token, expected end of statement");
4588 clearFeatureBits(Mips::FeatureDSP, "dsp");
4589 getTargetStreamer().emitDirectiveSetNoDsp();
4593 bool MipsAsmParser::parseSetMips16Directive() {
4594 MCAsmParser &Parser = getParser();
4595 Parser.Lex(); // Eat "mips16".
4597 // If this is not the end of the statement, report an error.
4598 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4599 reportParseError("unexpected token, expected end of statement");
4603 setFeatureBits(Mips::FeatureMips16, "mips16");
4604 getTargetStreamer().emitDirectiveSetMips16();
4605 Parser.Lex(); // Consume the EndOfStatement.
4609 bool MipsAsmParser::parseSetNoMips16Directive() {
4610 MCAsmParser &Parser = getParser();
4611 Parser.Lex(); // Eat "nomips16".
4613 // If this is not the end of the statement, report an error.
4614 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4615 reportParseError("unexpected token, expected end of statement");
4619 clearFeatureBits(Mips::FeatureMips16, "mips16");
4620 getTargetStreamer().emitDirectiveSetNoMips16();
4621 Parser.Lex(); // Consume the EndOfStatement.
4625 bool MipsAsmParser::parseSetFpDirective() {
4626 MCAsmParser &Parser = getParser();
4627 MipsABIFlagsSection::FpABIKind FpAbiVal;
4628 // Line can be: .set fp=32
4631 Parser.Lex(); // Eat fp token
4632 AsmToken Tok = Parser.getTok();
4633 if (Tok.isNot(AsmToken::Equal)) {
4634 reportParseError("unexpected token, expected equals sign '='");
4637 Parser.Lex(); // Eat '=' token.
4638 Tok = Parser.getTok();
4640 if (!parseFpABIValue(FpAbiVal, ".set"))
4643 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4644 reportParseError("unexpected token, expected end of statement");
4647 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4648 Parser.Lex(); // Consume the EndOfStatement.
4652 bool MipsAsmParser::parseSetOddSPRegDirective() {
4653 MCAsmParser &Parser = getParser();
4655 Parser.Lex(); // Eat "oddspreg".
4656 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4657 reportParseError("unexpected token, expected end of statement");
4661 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4662 getTargetStreamer().emitDirectiveSetOddSPReg();
4666 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4667 MCAsmParser &Parser = getParser();
4669 Parser.Lex(); // Eat "nooddspreg".
4670 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4671 reportParseError("unexpected token, expected end of statement");
4675 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4676 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4680 bool MipsAsmParser::parseSetPopDirective() {
4681 MCAsmParser &Parser = getParser();
4682 SMLoc Loc = getLexer().getLoc();
4685 if (getLexer().isNot(AsmToken::EndOfStatement))
4686 return reportParseError("unexpected token, expected end of statement");
4688 // Always keep an element on the options "stack" to prevent the user
4689 // from changing the initial options. This is how we remember them.
4690 if (AssemblerOptions.size() == 2)
4691 return reportParseError(Loc, ".set pop with no .set push");
4693 AssemblerOptions.pop_back();
4694 setAvailableFeatures(
4695 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4696 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4698 getTargetStreamer().emitDirectiveSetPop();
4702 bool MipsAsmParser::parseSetPushDirective() {
4703 MCAsmParser &Parser = getParser();
4705 if (getLexer().isNot(AsmToken::EndOfStatement))
4706 return reportParseError("unexpected token, expected end of statement");
4708 // Create a copy of the current assembler options environment and push it.
4709 AssemblerOptions.push_back(
4710 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4712 getTargetStreamer().emitDirectiveSetPush();
4716 bool MipsAsmParser::parseSetSoftFloatDirective() {
4717 MCAsmParser &Parser = getParser();
4719 if (getLexer().isNot(AsmToken::EndOfStatement))
4720 return reportParseError("unexpected token, expected end of statement");
4722 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4723 getTargetStreamer().emitDirectiveSetSoftFloat();
4727 bool MipsAsmParser::parseSetHardFloatDirective() {
4728 MCAsmParser &Parser = getParser();
4730 if (getLexer().isNot(AsmToken::EndOfStatement))
4731 return reportParseError("unexpected token, expected end of statement");
4733 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4734 getTargetStreamer().emitDirectiveSetHardFloat();
4738 bool MipsAsmParser::parseSetAssignment() {
4740 const MCExpr *Value;
4741 MCAsmParser &Parser = getParser();
4743 if (Parser.parseIdentifier(Name))
4744 reportParseError("expected identifier after .set");
4746 if (getLexer().isNot(AsmToken::Comma))
4747 return reportParseError("unexpected token, expected comma");
4750 if (Parser.parseExpression(Value))
4751 return reportParseError("expected valid expression after comma");
4753 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4754 Sym->setVariableValue(Value);
4759 bool MipsAsmParser::parseSetMips0Directive() {
4760 MCAsmParser &Parser = getParser();
4762 if (getLexer().isNot(AsmToken::EndOfStatement))
4763 return reportParseError("unexpected token, expected end of statement");
4765 // Reset assembler options to their initial values.
4766 setAvailableFeatures(
4767 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4768 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4769 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4771 getTargetStreamer().emitDirectiveSetMips0();
4775 bool MipsAsmParser::parseSetArchDirective() {
4776 MCAsmParser &Parser = getParser();
4778 if (getLexer().isNot(AsmToken::Equal))
4779 return reportParseError("unexpected token, expected equals sign");
4783 if (Parser.parseIdentifier(Arch))
4784 return reportParseError("expected arch identifier");
4786 StringRef ArchFeatureName =
4787 StringSwitch<StringRef>(Arch)
4788 .Case("mips1", "mips1")
4789 .Case("mips2", "mips2")
4790 .Case("mips3", "mips3")
4791 .Case("mips4", "mips4")
4792 .Case("mips5", "mips5")
4793 .Case("mips32", "mips32")
4794 .Case("mips32r2", "mips32r2")
4795 .Case("mips32r3", "mips32r3")
4796 .Case("mips32r5", "mips32r5")
4797 .Case("mips32r6", "mips32r6")
4798 .Case("mips64", "mips64")
4799 .Case("mips64r2", "mips64r2")
4800 .Case("mips64r3", "mips64r3")
4801 .Case("mips64r5", "mips64r5")
4802 .Case("mips64r6", "mips64r6")
4803 .Case("cnmips", "cnmips")
4804 .Case("r4000", "mips3") // This is an implementation of Mips3.
4807 if (ArchFeatureName.empty())
4808 return reportParseError("unsupported architecture");
4810 selectArch(ArchFeatureName);
4811 getTargetStreamer().emitDirectiveSetArch(Arch);
4815 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4816 MCAsmParser &Parser = getParser();
4818 if (getLexer().isNot(AsmToken::EndOfStatement))
4819 return reportParseError("unexpected token, expected end of statement");
4823 llvm_unreachable("Unimplemented feature");
4824 case Mips::FeatureDSP:
4825 setFeatureBits(Mips::FeatureDSP, "dsp");
4826 getTargetStreamer().emitDirectiveSetDsp();
4828 case Mips::FeatureMicroMips:
4829 getTargetStreamer().emitDirectiveSetMicroMips();
4831 case Mips::FeatureMips1:
4832 selectArch("mips1");
4833 getTargetStreamer().emitDirectiveSetMips1();
4835 case Mips::FeatureMips2:
4836 selectArch("mips2");
4837 getTargetStreamer().emitDirectiveSetMips2();
4839 case Mips::FeatureMips3:
4840 selectArch("mips3");
4841 getTargetStreamer().emitDirectiveSetMips3();
4843 case Mips::FeatureMips4:
4844 selectArch("mips4");
4845 getTargetStreamer().emitDirectiveSetMips4();
4847 case Mips::FeatureMips5:
4848 selectArch("mips5");
4849 getTargetStreamer().emitDirectiveSetMips5();
4851 case Mips::FeatureMips32:
4852 selectArch("mips32");
4853 getTargetStreamer().emitDirectiveSetMips32();
4855 case Mips::FeatureMips32r2:
4856 selectArch("mips32r2");
4857 getTargetStreamer().emitDirectiveSetMips32R2();
4859 case Mips::FeatureMips32r3:
4860 selectArch("mips32r3");
4861 getTargetStreamer().emitDirectiveSetMips32R3();
4863 case Mips::FeatureMips32r5:
4864 selectArch("mips32r5");
4865 getTargetStreamer().emitDirectiveSetMips32R5();
4867 case Mips::FeatureMips32r6:
4868 selectArch("mips32r6");
4869 getTargetStreamer().emitDirectiveSetMips32R6();
4871 case Mips::FeatureMips64:
4872 selectArch("mips64");
4873 getTargetStreamer().emitDirectiveSetMips64();
4875 case Mips::FeatureMips64r2:
4876 selectArch("mips64r2");
4877 getTargetStreamer().emitDirectiveSetMips64R2();
4879 case Mips::FeatureMips64r3:
4880 selectArch("mips64r3");
4881 getTargetStreamer().emitDirectiveSetMips64R3();
4883 case Mips::FeatureMips64r5:
4884 selectArch("mips64r5");
4885 getTargetStreamer().emitDirectiveSetMips64R5();
4887 case Mips::FeatureMips64r6:
4888 selectArch("mips64r6");
4889 getTargetStreamer().emitDirectiveSetMips64R6();
4895 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4896 MCAsmParser &Parser = getParser();
4897 if (getLexer().isNot(AsmToken::Comma)) {
4898 SMLoc Loc = getLexer().getLoc();
4899 Parser.eatToEndOfStatement();
4900 return Error(Loc, ErrorStr);
4903 Parser.Lex(); // Eat the comma.
4907 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4908 // In this class, it is only used for .cprestore.
4909 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4910 // MipsTargetELFStreamer and MipsAsmParser.
4911 bool MipsAsmParser::isPicAndNotNxxAbi() {
4912 return inPicMode() && !(isABI_N32() || isABI_N64());
4915 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4916 if (AssemblerOptions.back()->isReorder())
4917 Warning(Loc, ".cpload should be inside a noreorder section");
4919 if (inMips16Mode()) {
4920 reportParseError(".cpload is not supported in Mips16 mode");
4924 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4925 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4926 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4927 reportParseError("expected register containing function address");
4931 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4932 if (!RegOpnd.isGPRAsmReg()) {
4933 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4937 // If this is not the end of the statement, report an error.
4938 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4939 reportParseError("unexpected token, expected end of statement");
4943 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4947 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4948 MCAsmParser &Parser = getParser();
4950 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4951 // is used in non-PIC mode.
4953 if (inMips16Mode()) {
4954 reportParseError(".cprestore is not supported in Mips16 mode");
4958 // Get the stack offset value.
4959 const MCExpr *StackOffset;
4960 int64_t StackOffsetVal;
4961 if (Parser.parseExpression(StackOffset)) {
4962 reportParseError("expected stack offset value");
4966 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4967 reportParseError("stack offset is not an absolute expression");
4971 if (StackOffsetVal < 0) {
4972 Warning(Loc, ".cprestore with negative stack offset has no effect");
4973 IsCpRestoreSet = false;
4975 IsCpRestoreSet = true;
4976 CpRestoreOffset = StackOffsetVal;
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 // Store the $gp on the stack.
4986 SmallVector<MCInst, 3> StoreInsts;
4987 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
4990 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
4991 Parser.Lex(); // Consume the EndOfStatement.
4995 bool MipsAsmParser::parseDirectiveCPSetup() {
4996 MCAsmParser &Parser = getParser();
4999 bool SaveIsReg = true;
5001 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5002 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5003 if (ResTy == MatchOperand_NoMatch) {
5004 reportParseError("expected register containing function address");
5005 Parser.eatToEndOfStatement();
5009 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5010 if (!FuncRegOpnd.isGPRAsmReg()) {
5011 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5012 Parser.eatToEndOfStatement();
5016 FuncReg = FuncRegOpnd.getGPR32Reg();
5019 if (!eatComma("unexpected token, expected comma"))
5022 ResTy = parseAnyRegister(TmpReg);
5023 if (ResTy == MatchOperand_NoMatch) {
5024 const MCExpr *OffsetExpr;
5026 SMLoc ExprLoc = getLexer().getLoc();
5028 if (Parser.parseExpression(OffsetExpr) ||
5029 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5030 reportParseError(ExprLoc, "expected save register or stack offset");
5031 Parser.eatToEndOfStatement();
5038 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5039 if (!SaveOpnd.isGPRAsmReg()) {
5040 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5041 Parser.eatToEndOfStatement();
5044 Save = SaveOpnd.getGPR32Reg();
5047 if (!eatComma("unexpected token, expected comma"))
5051 if (Parser.parseExpression(Expr)) {
5052 reportParseError("expected expression");
5056 if (Expr->getKind() != MCExpr::SymbolRef) {
5057 reportParseError("expected symbol");
5060 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5062 CpSaveLocation = Save;
5063 CpSaveLocationIsRegister = SaveIsReg;
5065 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5070 bool MipsAsmParser::parseDirectiveCPReturn() {
5071 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5072 CpSaveLocationIsRegister);
5076 bool MipsAsmParser::parseDirectiveNaN() {
5077 MCAsmParser &Parser = getParser();
5078 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5079 const AsmToken &Tok = Parser.getTok();
5081 if (Tok.getString() == "2008") {
5083 getTargetStreamer().emitDirectiveNaN2008();
5085 } else if (Tok.getString() == "legacy") {
5087 getTargetStreamer().emitDirectiveNaNLegacy();
5091 // If we don't recognize the option passed to the .nan
5092 // directive (e.g. no option or unknown option), emit an error.
5093 reportParseError("invalid option in .nan directive");
5097 bool MipsAsmParser::parseDirectiveSet() {
5098 MCAsmParser &Parser = getParser();
5099 // Get the next token.
5100 const AsmToken &Tok = Parser.getTok();
5102 if (Tok.getString() == "noat") {
5103 return parseSetNoAtDirective();
5104 } else if (Tok.getString() == "at") {
5105 return parseSetAtDirective();
5106 } else if (Tok.getString() == "arch") {
5107 return parseSetArchDirective();
5108 } else if (Tok.getString() == "fp") {
5109 return parseSetFpDirective();
5110 } else if (Tok.getString() == "oddspreg") {
5111 return parseSetOddSPRegDirective();
5112 } else if (Tok.getString() == "nooddspreg") {
5113 return parseSetNoOddSPRegDirective();
5114 } else if (Tok.getString() == "pop") {
5115 return parseSetPopDirective();
5116 } else if (Tok.getString() == "push") {
5117 return parseSetPushDirective();
5118 } else if (Tok.getString() == "reorder") {
5119 return parseSetReorderDirective();
5120 } else if (Tok.getString() == "noreorder") {
5121 return parseSetNoReorderDirective();
5122 } else if (Tok.getString() == "macro") {
5123 return parseSetMacroDirective();
5124 } else if (Tok.getString() == "nomacro") {
5125 return parseSetNoMacroDirective();
5126 } else if (Tok.getString() == "mips16") {
5127 return parseSetMips16Directive();
5128 } else if (Tok.getString() == "nomips16") {
5129 return parseSetNoMips16Directive();
5130 } else if (Tok.getString() == "nomicromips") {
5131 getTargetStreamer().emitDirectiveSetNoMicroMips();
5132 Parser.eatToEndOfStatement();
5134 } else if (Tok.getString() == "micromips") {
5135 return parseSetFeature(Mips::FeatureMicroMips);
5136 } else if (Tok.getString() == "mips0") {
5137 return parseSetMips0Directive();
5138 } else if (Tok.getString() == "mips1") {
5139 return parseSetFeature(Mips::FeatureMips1);
5140 } else if (Tok.getString() == "mips2") {
5141 return parseSetFeature(Mips::FeatureMips2);
5142 } else if (Tok.getString() == "mips3") {
5143 return parseSetFeature(Mips::FeatureMips3);
5144 } else if (Tok.getString() == "mips4") {
5145 return parseSetFeature(Mips::FeatureMips4);
5146 } else if (Tok.getString() == "mips5") {
5147 return parseSetFeature(Mips::FeatureMips5);
5148 } else if (Tok.getString() == "mips32") {
5149 return parseSetFeature(Mips::FeatureMips32);
5150 } else if (Tok.getString() == "mips32r2") {
5151 return parseSetFeature(Mips::FeatureMips32r2);
5152 } else if (Tok.getString() == "mips32r3") {
5153 return parseSetFeature(Mips::FeatureMips32r3);
5154 } else if (Tok.getString() == "mips32r5") {
5155 return parseSetFeature(Mips::FeatureMips32r5);
5156 } else if (Tok.getString() == "mips32r6") {
5157 return parseSetFeature(Mips::FeatureMips32r6);
5158 } else if (Tok.getString() == "mips64") {
5159 return parseSetFeature(Mips::FeatureMips64);
5160 } else if (Tok.getString() == "mips64r2") {
5161 return parseSetFeature(Mips::FeatureMips64r2);
5162 } else if (Tok.getString() == "mips64r3") {
5163 return parseSetFeature(Mips::FeatureMips64r3);
5164 } else if (Tok.getString() == "mips64r5") {
5165 return parseSetFeature(Mips::FeatureMips64r5);
5166 } else if (Tok.getString() == "mips64r6") {
5167 return parseSetFeature(Mips::FeatureMips64r6);
5168 } else if (Tok.getString() == "dsp") {
5169 return parseSetFeature(Mips::FeatureDSP);
5170 } else if (Tok.getString() == "nodsp") {
5171 return parseSetNoDspDirective();
5172 } else if (Tok.getString() == "msa") {
5173 return parseSetMsaDirective();
5174 } else if (Tok.getString() == "nomsa") {
5175 return parseSetNoMsaDirective();
5176 } else if (Tok.getString() == "softfloat") {
5177 return parseSetSoftFloatDirective();
5178 } else if (Tok.getString() == "hardfloat") {
5179 return parseSetHardFloatDirective();
5181 // It is just an identifier, look for an assignment.
5182 parseSetAssignment();
5189 /// parseDataDirective
5190 /// ::= .word [ expression (, expression)* ]
5191 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5192 MCAsmParser &Parser = getParser();
5193 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5195 const MCExpr *Value;
5196 if (getParser().parseExpression(Value))
5199 getParser().getStreamer().EmitValue(Value, Size);
5201 if (getLexer().is(AsmToken::EndOfStatement))
5204 if (getLexer().isNot(AsmToken::Comma))
5205 return Error(L, "unexpected token, expected comma");
5214 /// parseDirectiveGpWord
5215 /// ::= .gpword local_sym
5216 bool MipsAsmParser::parseDirectiveGpWord() {
5217 MCAsmParser &Parser = getParser();
5218 const MCExpr *Value;
5219 // EmitGPRel32Value requires an expression, so we are using base class
5220 // method to evaluate the expression.
5221 if (getParser().parseExpression(Value))
5223 getParser().getStreamer().EmitGPRel32Value(Value);
5225 if (getLexer().isNot(AsmToken::EndOfStatement))
5226 return Error(getLexer().getLoc(),
5227 "unexpected token, expected end of statement");
5228 Parser.Lex(); // Eat EndOfStatement token.
5232 /// parseDirectiveGpDWord
5233 /// ::= .gpdword local_sym
5234 bool MipsAsmParser::parseDirectiveGpDWord() {
5235 MCAsmParser &Parser = getParser();
5236 const MCExpr *Value;
5237 // EmitGPRel64Value requires an expression, so we are using base class
5238 // method to evaluate the expression.
5239 if (getParser().parseExpression(Value))
5241 getParser().getStreamer().EmitGPRel64Value(Value);
5243 if (getLexer().isNot(AsmToken::EndOfStatement))
5244 return Error(getLexer().getLoc(),
5245 "unexpected token, expected end of statement");
5246 Parser.Lex(); // Eat EndOfStatement token.
5250 bool MipsAsmParser::parseDirectiveOption() {
5251 MCAsmParser &Parser = getParser();
5252 // Get the option token.
5253 AsmToken Tok = Parser.getTok();
5254 // At the moment only identifiers are supported.
5255 if (Tok.isNot(AsmToken::Identifier)) {
5256 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5257 Parser.eatToEndOfStatement();
5261 StringRef Option = Tok.getIdentifier();
5263 if (Option == "pic0") {
5264 // MipsAsmParser needs to know if the current PIC mode changes.
5265 IsPicEnabled = false;
5267 getTargetStreamer().emitDirectiveOptionPic0();
5269 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5270 Error(Parser.getTok().getLoc(),
5271 "unexpected token, expected end of statement");
5272 Parser.eatToEndOfStatement();
5277 if (Option == "pic2") {
5278 // MipsAsmParser needs to know if the current PIC mode changes.
5279 IsPicEnabled = true;
5281 getTargetStreamer().emitDirectiveOptionPic2();
5283 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5284 Error(Parser.getTok().getLoc(),
5285 "unexpected token, expected end of statement");
5286 Parser.eatToEndOfStatement();
5292 Warning(Parser.getTok().getLoc(),
5293 "unknown option, expected 'pic0' or 'pic2'");
5294 Parser.eatToEndOfStatement();
5298 /// parseInsnDirective
5300 bool MipsAsmParser::parseInsnDirective() {
5301 // If this is not the end of the statement, report an error.
5302 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5303 reportParseError("unexpected token, expected end of statement");
5307 // The actual label marking happens in
5308 // MipsELFStreamer::createPendingLabelRelocs().
5309 getTargetStreamer().emitDirectiveInsn();
5311 getParser().Lex(); // Eat EndOfStatement token.
5315 /// parseDirectiveModule
5316 /// ::= .module oddspreg
5317 /// ::= .module nooddspreg
5318 /// ::= .module fp=value
5319 /// ::= .module softfloat
5320 /// ::= .module hardfloat
5321 bool MipsAsmParser::parseDirectiveModule() {
5322 MCAsmParser &Parser = getParser();
5323 MCAsmLexer &Lexer = getLexer();
5324 SMLoc L = Lexer.getLoc();
5326 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5327 // TODO : get a better message.
5328 reportParseError(".module directive must appear before any code");
5333 if (Parser.parseIdentifier(Option)) {
5334 reportParseError("expected .module option identifier");
5338 if (Option == "oddspreg") {
5339 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5341 // Synchronize the abiflags information with the FeatureBits information we
5343 getTargetStreamer().updateABIInfo(*this);
5345 // If printing assembly, use the recently updated abiflags information.
5346 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5347 // emitted at the end).
5348 getTargetStreamer().emitDirectiveModuleOddSPReg();
5350 // If this is not the end of the statement, report an error.
5351 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5352 reportParseError("unexpected token, expected end of statement");
5356 return false; // parseDirectiveModule has finished successfully.
5357 } else if (Option == "nooddspreg") {
5359 Error(L, "'.module nooddspreg' requires the O32 ABI");
5363 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5365 // Synchronize the abiflags information with the FeatureBits information we
5367 getTargetStreamer().updateABIInfo(*this);
5369 // If printing assembly, use the recently updated abiflags information.
5370 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5371 // emitted at the end).
5372 getTargetStreamer().emitDirectiveModuleOddSPReg();
5374 // If this is not the end of the statement, report an error.
5375 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5376 reportParseError("unexpected token, expected end of statement");
5380 return false; // parseDirectiveModule has finished successfully.
5381 } else if (Option == "fp") {
5382 return parseDirectiveModuleFP();
5383 } else if (Option == "softfloat") {
5384 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5386 // Synchronize the ABI Flags information with the FeatureBits information we
5388 getTargetStreamer().updateABIInfo(*this);
5390 // If printing assembly, use the recently updated ABI Flags information.
5391 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5393 getTargetStreamer().emitDirectiveModuleSoftFloat();
5395 // If this is not the end of the statement, report an error.
5396 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5397 reportParseError("unexpected token, expected end of statement");
5401 return false; // parseDirectiveModule has finished successfully.
5402 } else if (Option == "hardfloat") {
5403 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5405 // Synchronize the ABI Flags information with the FeatureBits information we
5407 getTargetStreamer().updateABIInfo(*this);
5409 // If printing assembly, use the recently updated ABI Flags information.
5410 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5412 getTargetStreamer().emitDirectiveModuleHardFloat();
5414 // If this is not the end of the statement, report an error.
5415 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5416 reportParseError("unexpected token, expected end of statement");
5420 return false; // parseDirectiveModule has finished successfully.
5422 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5426 /// parseDirectiveModuleFP
5430 bool MipsAsmParser::parseDirectiveModuleFP() {
5431 MCAsmParser &Parser = getParser();
5432 MCAsmLexer &Lexer = getLexer();
5434 if (Lexer.isNot(AsmToken::Equal)) {
5435 reportParseError("unexpected token, expected equals sign '='");
5438 Parser.Lex(); // Eat '=' token.
5440 MipsABIFlagsSection::FpABIKind FpABI;
5441 if (!parseFpABIValue(FpABI, ".module"))
5444 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5445 reportParseError("unexpected token, expected end of statement");
5449 // Synchronize the abiflags information with the FeatureBits information we
5451 getTargetStreamer().updateABIInfo(*this);
5453 // If printing assembly, use the recently updated abiflags information.
5454 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5455 // emitted at the end).
5456 getTargetStreamer().emitDirectiveModuleFP();
5458 Parser.Lex(); // Consume the EndOfStatement.
5462 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5463 StringRef Directive) {
5464 MCAsmParser &Parser = getParser();
5465 MCAsmLexer &Lexer = getLexer();
5466 bool ModuleLevelOptions = Directive == ".module";
5468 if (Lexer.is(AsmToken::Identifier)) {
5469 StringRef Value = Parser.getTok().getString();
5472 if (Value != "xx") {
5473 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5478 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5482 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5483 if (ModuleLevelOptions) {
5484 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5485 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5487 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5488 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5493 if (Lexer.is(AsmToken::Integer)) {
5494 unsigned Value = Parser.getTok().getIntVal();
5497 if (Value != 32 && Value != 64) {
5498 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5504 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5508 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5509 if (ModuleLevelOptions) {
5510 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5511 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5513 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5514 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5517 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5518 if (ModuleLevelOptions) {
5519 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5520 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5522 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5523 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5533 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5534 MCAsmParser &Parser = getParser();
5535 StringRef IDVal = DirectiveID.getString();
5537 if (IDVal == ".cpload")
5538 return parseDirectiveCpLoad(DirectiveID.getLoc());
5539 if (IDVal == ".cprestore")
5540 return parseDirectiveCpRestore(DirectiveID.getLoc());
5541 if (IDVal == ".dword") {
5542 parseDataDirective(8, DirectiveID.getLoc());
5545 if (IDVal == ".ent") {
5546 StringRef SymbolName;
5548 if (Parser.parseIdentifier(SymbolName)) {
5549 reportParseError("expected identifier after .ent");
5553 // There's an undocumented extension that allows an integer to
5554 // follow the name of the procedure which AFAICS is ignored by GAS.
5555 // Example: .ent foo,2
5556 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5557 if (getLexer().isNot(AsmToken::Comma)) {
5558 // Even though we accept this undocumented extension for compatibility
5559 // reasons, the additional integer argument does not actually change
5560 // the behaviour of the '.ent' directive, so we would like to discourage
5561 // its use. We do this by not referring to the extended version in
5562 // error messages which are not directly related to its use.
5563 reportParseError("unexpected token, expected end of statement");
5566 Parser.Lex(); // Eat the comma.
5567 const MCExpr *DummyNumber;
5568 int64_t DummyNumberVal;
5569 // If the user was explicitly trying to use the extended version,
5570 // we still give helpful extension-related error messages.
5571 if (Parser.parseExpression(DummyNumber)) {
5572 reportParseError("expected number after comma");
5575 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5576 reportParseError("expected an absolute expression after comma");
5581 // If this is not the end of the statement, report an error.
5582 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5583 reportParseError("unexpected token, expected end of statement");
5587 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5589 getTargetStreamer().emitDirectiveEnt(*Sym);
5591 IsCpRestoreSet = false;
5595 if (IDVal == ".end") {
5596 StringRef SymbolName;
5598 if (Parser.parseIdentifier(SymbolName)) {
5599 reportParseError("expected identifier after .end");
5603 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5604 reportParseError("unexpected token, expected end of statement");
5608 if (CurrentFn == nullptr) {
5609 reportParseError(".end used without .ent");
5613 if ((SymbolName != CurrentFn->getName())) {
5614 reportParseError(".end symbol does not match .ent symbol");
5618 getTargetStreamer().emitDirectiveEnd(SymbolName);
5619 CurrentFn = nullptr;
5620 IsCpRestoreSet = false;
5624 if (IDVal == ".frame") {
5625 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5626 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5627 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5628 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5629 reportParseError("expected stack register");
5633 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5634 if (!StackRegOpnd.isGPRAsmReg()) {
5635 reportParseError(StackRegOpnd.getStartLoc(),
5636 "expected general purpose register");
5639 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5641 if (Parser.getTok().is(AsmToken::Comma))
5644 reportParseError("unexpected token, expected comma");
5648 // Parse the frame size.
5649 const MCExpr *FrameSize;
5650 int64_t FrameSizeVal;
5652 if (Parser.parseExpression(FrameSize)) {
5653 reportParseError("expected frame size value");
5657 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5658 reportParseError("frame size not an absolute expression");
5662 if (Parser.getTok().is(AsmToken::Comma))
5665 reportParseError("unexpected token, expected comma");
5669 // Parse the return register.
5671 ResTy = parseAnyRegister(TmpReg);
5672 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5673 reportParseError("expected return register");
5677 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5678 if (!ReturnRegOpnd.isGPRAsmReg()) {
5679 reportParseError(ReturnRegOpnd.getStartLoc(),
5680 "expected general purpose register");
5684 // If this is not the end of the statement, report an error.
5685 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5686 reportParseError("unexpected token, expected end of statement");
5690 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5691 ReturnRegOpnd.getGPR32Reg());
5692 IsCpRestoreSet = false;
5696 if (IDVal == ".set") {
5697 return parseDirectiveSet();
5700 if (IDVal == ".mask" || IDVal == ".fmask") {
5701 // .mask bitmask, frame_offset
5702 // bitmask: One bit for each register used.
5703 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5704 // first register is expected to be saved.
5706 // .mask 0x80000000, -4
5707 // .fmask 0x80000000, -4
5710 // Parse the bitmask
5711 const MCExpr *BitMask;
5714 if (Parser.parseExpression(BitMask)) {
5715 reportParseError("expected bitmask value");
5719 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5720 reportParseError("bitmask not an absolute expression");
5724 if (Parser.getTok().is(AsmToken::Comma))
5727 reportParseError("unexpected token, expected comma");
5731 // Parse the frame_offset
5732 const MCExpr *FrameOffset;
5733 int64_t FrameOffsetVal;
5735 if (Parser.parseExpression(FrameOffset)) {
5736 reportParseError("expected frame offset value");
5740 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5741 reportParseError("frame offset not an absolute expression");
5745 // If this is not the end of the statement, report an error.
5746 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5747 reportParseError("unexpected token, expected end of statement");
5751 if (IDVal == ".mask")
5752 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5754 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5758 if (IDVal == ".nan")
5759 return parseDirectiveNaN();
5761 if (IDVal == ".gpword") {
5762 parseDirectiveGpWord();
5766 if (IDVal == ".gpdword") {
5767 parseDirectiveGpDWord();
5771 if (IDVal == ".word") {
5772 parseDataDirective(4, DirectiveID.getLoc());
5776 if (IDVal == ".option")
5777 return parseDirectiveOption();
5779 if (IDVal == ".abicalls") {
5780 getTargetStreamer().emitDirectiveAbiCalls();
5781 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5782 Error(Parser.getTok().getLoc(),
5783 "unexpected token, expected end of statement");
5785 Parser.eatToEndOfStatement();
5790 if (IDVal == ".cpsetup")
5791 return parseDirectiveCPSetup();
5793 if (IDVal == ".cpreturn")
5794 return parseDirectiveCPReturn();
5796 if (IDVal == ".module")
5797 return parseDirectiveModule();
5799 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5800 return parseInternalDirectiveReallowModule();
5802 if (IDVal == ".insn")
5803 return parseInsnDirective();
5808 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5809 // If this is not the end of the statement, report an error.
5810 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5811 reportParseError("unexpected token, expected end of statement");
5815 getTargetStreamer().reallowModuleDirective();
5817 getParser().Lex(); // Eat EndOfStatement token.
5821 extern "C" void LLVMInitializeMipsAsmParser() {
5822 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5823 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5824 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5825 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5828 #define GET_REGISTER_MATCHER
5829 #define GET_MATCHER_IMPLEMENTATION
5830 #include "MipsGenAsmMatcher.inc"