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)
1013 unsigned R0 = RegList.List->front();
1014 unsigned R1 = RegList.List->back();
1015 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1016 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1019 int PrevReg = *RegList.List->begin();
1020 for (int i = 1; i < Size - 1; i++) {
1021 int Reg = (*(RegList.List))[i];
1022 if ( Reg != PrevReg + 1)
1029 bool isInvNum() const { return Kind == k_Immediate; }
1030 bool isLSAImm() const {
1031 if (!isConstantImm())
1033 int64_t Val = getConstantImm();
1034 return 1 <= Val && Val <= 4;
1036 bool isRegList() const { return Kind == k_RegList; }
1037 bool isMovePRegPair() const {
1038 if (Kind != k_RegList || RegList.List->size() != 2)
1041 unsigned R0 = RegList.List->front();
1042 unsigned R1 = RegList.List->back();
1044 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1045 (R0 == Mips::A1 && R1 == Mips::A3) ||
1046 (R0 == Mips::A2 && R1 == Mips::A3) ||
1047 (R0 == Mips::A0 && R1 == Mips::S5) ||
1048 (R0 == Mips::A0 && R1 == Mips::S6) ||
1049 (R0 == Mips::A0 && R1 == Mips::A1) ||
1050 (R0 == Mips::A0 && R1 == Mips::A2) ||
1051 (R0 == Mips::A0 && R1 == Mips::A3))
1057 StringRef getToken() const {
1058 assert(Kind == k_Token && "Invalid access!");
1059 return StringRef(Tok.Data, Tok.Length);
1061 bool isRegPair() const { return Kind == k_RegPair; }
1063 unsigned getReg() const override {
1064 // As a special case until we sort out the definition of div/divu, pretend
1065 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1066 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1067 RegIdx.Kind & RegKind_GPR)
1068 return getGPR32Reg(); // FIXME: GPR64 too
1070 assert(Kind == k_PhysRegister && "Invalid access!");
1074 const MCExpr *getImm() const {
1075 assert((Kind == k_Immediate) && "Invalid access!");
1079 int64_t getConstantImm() const {
1080 const MCExpr *Val = getImm();
1081 return static_cast<const MCConstantExpr *>(Val)->getValue();
1084 MipsOperand *getMemBase() const {
1085 assert((Kind == k_Memory) && "Invalid access!");
1089 const MCExpr *getMemOff() const {
1090 assert((Kind == k_Memory) && "Invalid access!");
1094 int64_t getConstantMemOff() const {
1095 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1098 const SmallVectorImpl<unsigned> &getRegList() const {
1099 assert((Kind == k_RegList) && "Invalid access!");
1100 return *(RegList.List);
1103 unsigned getRegPair() const {
1104 assert((Kind == k_RegPair) && "Invalid access!");
1105 return RegIdx.Index;
1108 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1109 MipsAsmParser &Parser) {
1110 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1111 Op->Tok.Data = Str.data();
1112 Op->Tok.Length = Str.size();
1118 /// Create a numeric register (e.g. $1). The exact register remains
1119 /// unresolved until an instruction successfully matches
1120 static std::unique_ptr<MipsOperand>
1121 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1122 SMLoc E, MipsAsmParser &Parser) {
1123 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1124 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1127 /// Create a register that is definitely a GPR.
1128 /// This is typically only used for named registers such as $gp.
1129 static std::unique_ptr<MipsOperand>
1130 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1131 MipsAsmParser &Parser) {
1132 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1135 /// Create a register that is definitely a FGR.
1136 /// This is typically only used for named registers such as $f0.
1137 static std::unique_ptr<MipsOperand>
1138 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1139 MipsAsmParser &Parser) {
1140 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1143 /// Create a register that is definitely a HWReg.
1144 /// This is typically only used for named registers such as $hwr_cpunum.
1145 static std::unique_ptr<MipsOperand>
1146 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1147 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1148 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1151 /// Create a register that is definitely an FCC.
1152 /// This is typically only used for named registers such as $fcc0.
1153 static std::unique_ptr<MipsOperand>
1154 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1155 MipsAsmParser &Parser) {
1156 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1159 /// Create a register that is definitely an ACC.
1160 /// This is typically only used for named registers such as $ac0.
1161 static std::unique_ptr<MipsOperand>
1162 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1163 MipsAsmParser &Parser) {
1164 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1167 /// Create a register that is definitely an MSA128.
1168 /// This is typically only used for named registers such as $w0.
1169 static std::unique_ptr<MipsOperand>
1170 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1171 SMLoc E, MipsAsmParser &Parser) {
1172 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1175 /// Create a register that is definitely an MSACtrl.
1176 /// This is typically only used for named registers such as $msaaccess.
1177 static std::unique_ptr<MipsOperand>
1178 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1179 SMLoc E, MipsAsmParser &Parser) {
1180 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1183 static std::unique_ptr<MipsOperand>
1184 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1185 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1192 static std::unique_ptr<MipsOperand>
1193 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1194 SMLoc E, MipsAsmParser &Parser) {
1195 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1196 Op->Mem.Base = Base.release();
1203 static std::unique_ptr<MipsOperand>
1204 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1205 MipsAsmParser &Parser) {
1206 assert (Regs.size() > 0 && "Empty list not allowed");
1208 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1209 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1210 Op->StartLoc = StartLoc;
1211 Op->EndLoc = EndLoc;
1215 static std::unique_ptr<MipsOperand>
1216 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1217 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1218 Op->RegIdx.Index = RegNo;
1224 bool isGPRAsmReg() const {
1225 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1227 bool isMM16AsmReg() const {
1228 if (!(isRegIdx() && RegIdx.Kind))
1230 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1231 || RegIdx.Index == 16 || RegIdx.Index == 17);
1233 bool isMM16AsmRegZero() const {
1234 if (!(isRegIdx() && RegIdx.Kind))
1236 return (RegIdx.Index == 0 ||
1237 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1238 RegIdx.Index == 17);
1240 bool isMM16AsmRegMoveP() const {
1241 if (!(isRegIdx() && RegIdx.Kind))
1243 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1244 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1246 bool isFGRAsmReg() const {
1247 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1248 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1250 bool isHWRegsAsmReg() const {
1251 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1253 bool isCCRAsmReg() const {
1254 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1256 bool isFCCAsmReg() const {
1257 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1259 if (!AsmParser.hasEightFccRegisters())
1260 return RegIdx.Index == 0;
1261 return RegIdx.Index <= 7;
1263 bool isACCAsmReg() const {
1264 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1266 bool isCOP0AsmReg() const {
1267 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1269 bool isCOP2AsmReg() const {
1270 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1272 bool isCOP3AsmReg() const {
1273 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1275 bool isMSA128AsmReg() const {
1276 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1278 bool isMSACtrlAsmReg() const {
1279 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1282 /// getStartLoc - Get the location of the first token of this operand.
1283 SMLoc getStartLoc() const override { return StartLoc; }
1284 /// getEndLoc - Get the location of the last token of this operand.
1285 SMLoc getEndLoc() const override { return EndLoc; }
1287 virtual ~MipsOperand() {
1295 delete RegList.List;
1296 case k_PhysRegister:
1297 case k_RegisterIndex:
1304 void print(raw_ostream &OS) const override {
1313 Mem.Base->print(OS);
1318 case k_PhysRegister:
1319 OS << "PhysReg<" << PhysReg.Num << ">";
1321 case k_RegisterIndex:
1322 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1329 for (auto Reg : (*RegList.List))
1334 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1338 }; // class MipsOperand
1342 extern const MCInstrDesc MipsInsts[];
1344 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1345 return MipsInsts[Opcode];
1348 static bool hasShortDelaySlot(unsigned Opcode) {
1351 case Mips::JALRS_MM:
1352 case Mips::JALRS16_MM:
1353 case Mips::BGEZALS_MM:
1354 case Mips::BLTZALS_MM:
1361 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1362 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1363 return &SRExpr->getSymbol();
1366 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1367 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1368 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1379 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1380 return getSingleMCSymbol(UExpr->getSubExpr());
1385 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1386 if (isa<MCSymbolRefExpr>(Expr))
1389 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1390 return countMCSymbolRefExpr(BExpr->getLHS()) +
1391 countMCSymbolRefExpr(BExpr->getRHS());
1393 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1394 return countMCSymbolRefExpr(UExpr->getSubExpr());
1400 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1401 SmallVectorImpl<MCInst> &Instructions) {
1403 tmpInst.setOpcode(Opcode);
1404 tmpInst.addOperand(MCOperand::createReg(Reg0));
1405 tmpInst.addOperand(Op1);
1406 tmpInst.setLoc(IDLoc);
1407 Instructions.push_back(tmpInst);
1410 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1411 SmallVectorImpl<MCInst> &Instructions) {
1412 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1415 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1416 SmallVectorImpl<MCInst> &Instructions) {
1417 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1420 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1421 SmallVectorImpl<MCInst> &Instructions) {
1423 tmpInst.setOpcode(Opcode);
1424 tmpInst.addOperand(MCOperand::createImm(Imm1));
1425 tmpInst.addOperand(MCOperand::createImm(Imm2));
1426 tmpInst.setLoc(IDLoc);
1427 Instructions.push_back(tmpInst);
1430 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1431 SmallVectorImpl<MCInst> &Instructions) {
1433 tmpInst.setOpcode(Opcode);
1434 tmpInst.addOperand(MCOperand::createReg(Reg0));
1435 tmpInst.setLoc(IDLoc);
1436 Instructions.push_back(tmpInst);
1439 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1440 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1442 tmpInst.setOpcode(Opcode);
1443 tmpInst.addOperand(MCOperand::createReg(Reg0));
1444 tmpInst.addOperand(MCOperand::createReg(Reg1));
1445 tmpInst.addOperand(Op2);
1446 tmpInst.setLoc(IDLoc);
1447 Instructions.push_back(tmpInst);
1450 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1451 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1452 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1456 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1457 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1458 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1462 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1463 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1464 if (ShiftAmount >= 32) {
1465 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1470 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1472 } // end anonymous namespace.
1474 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1475 SmallVectorImpl<MCInst> &Instructions) {
1476 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1477 bool ExpandedJalSym = false;
1481 if (MCID.isBranch() || MCID.isCall()) {
1482 const unsigned Opcode = Inst.getOpcode();
1492 assert(hasCnMips() && "instruction only valid for octeon cpus");
1499 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1500 Offset = Inst.getOperand(2);
1501 if (!Offset.isImm())
1502 break; // We'll deal with this situation later on when applying fixups.
1503 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1504 return Error(IDLoc, "branch target out of range");
1505 if (OffsetToAlignment(Offset.getImm(),
1506 1LL << (inMicroMipsMode() ? 1 : 2)))
1507 return Error(IDLoc, "branch to misaligned address");
1521 case Mips::BGEZAL_MM:
1522 case Mips::BLTZAL_MM:
1525 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1526 Offset = Inst.getOperand(1);
1527 if (!Offset.isImm())
1528 break; // We'll deal with this situation later on when applying fixups.
1529 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1530 return Error(IDLoc, "branch target out of range");
1531 if (OffsetToAlignment(Offset.getImm(),
1532 1LL << (inMicroMipsMode() ? 1 : 2)))
1533 return Error(IDLoc, "branch to misaligned address");
1535 case Mips::BEQZ16_MM:
1536 case Mips::BEQZC16_MMR6:
1537 case Mips::BNEZ16_MM:
1538 case Mips::BNEZC16_MMR6:
1539 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1540 Offset = Inst.getOperand(1);
1541 if (!Offset.isImm())
1542 break; // We'll deal with this situation later on when applying fixups.
1543 if (!isInt<8>(Offset.getImm()))
1544 return Error(IDLoc, "branch target out of range");
1545 if (OffsetToAlignment(Offset.getImm(), 2LL))
1546 return Error(IDLoc, "branch to misaligned address");
1551 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1552 // We still accept it but it is a normal nop.
1553 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1554 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1555 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1560 const unsigned Opcode = Inst.getOpcode();
1572 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1573 // The offset is handled above
1574 Opnd = Inst.getOperand(1);
1576 return Error(IDLoc, "expected immediate operand kind");
1577 Imm = Opnd.getImm();
1578 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1579 Opcode == Mips::BBIT1 ? 63 : 31))
1580 return Error(IDLoc, "immediate operand value out of range");
1582 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1584 Inst.getOperand(1).setImm(Imm - 32);
1592 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1594 Opnd = Inst.getOperand(3);
1596 return Error(IDLoc, "expected immediate operand kind");
1597 Imm = Opnd.getImm();
1598 if (Imm < 0 || Imm > 31)
1599 return Error(IDLoc, "immediate operand value out of range");
1601 Opnd = Inst.getOperand(2);
1603 return Error(IDLoc, "expected immediate operand kind");
1604 Imm = Opnd.getImm();
1605 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1606 Opcode == Mips::EXTS ? 63 : 31))
1607 return Error(IDLoc, "immediate operand value out of range");
1609 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1610 Inst.getOperand(2).setImm(Imm - 32);
1616 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1617 Opnd = Inst.getOperand(2);
1619 return Error(IDLoc, "expected immediate operand kind");
1620 Imm = Opnd.getImm();
1621 if (!isInt<10>(Imm))
1622 return Error(IDLoc, "immediate operand value out of range");
1627 // This expansion is not in a function called by tryExpandInstruction()
1628 // because the pseudo-instruction doesn't have a distinct opcode.
1629 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1631 warnIfNoMacro(IDLoc);
1633 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1635 // We can do this expansion if there's only 1 symbol in the argument
1637 if (countMCSymbolRefExpr(JalExpr) > 1)
1638 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1640 // FIXME: This is checking the expression can be handled by the later stages
1641 // of the assembler. We ought to leave it to those later stages but
1642 // we can't do that until we stop evaluateRelocExpr() rewriting the
1643 // expressions into non-equivalent forms.
1644 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1646 // FIXME: Add support for label+offset operands (currently causes an error).
1647 // FIXME: Add support for forward-declared local symbols.
1648 // FIXME: Add expansion for when the LargeGOT option is enabled.
1649 if (JalSym->isInSection() || JalSym->isTemporary()) {
1651 // If it's a local symbol and the O32 ABI is being used, we expand to:
1653 // R_(MICRO)MIPS_GOT16 label
1654 // addiu $25, $25, 0
1655 // R_(MICRO)MIPS_LO16 label
1657 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1658 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1660 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1661 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1662 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1663 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1664 } else if (isABI_N32() || isABI_N64()) {
1665 // If it's a local symbol and the N32/N64 ABIs are being used,
1667 // lw/ld $25, 0($gp)
1668 // R_(MICRO)MIPS_GOT_DISP label
1670 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1672 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1673 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1676 // If it's an external/weak symbol, we expand to:
1677 // lw/ld $25, 0($gp)
1678 // R_(MICRO)MIPS_CALL16 label
1680 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1682 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1683 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1687 if (IsCpRestoreSet && inMicroMipsMode())
1688 JalrInst.setOpcode(Mips::JALRS_MM);
1690 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1691 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1692 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1694 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1695 // This relocation is supposed to be an optimization hint for the linker
1696 // and is not necessary for correctness.
1699 ExpandedJalSym = true;
1702 if (MCID.mayLoad() || MCID.mayStore()) {
1703 // Check the offset of memory operand, if it is a symbol
1704 // reference or immediate we may have to expand instructions.
1705 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1706 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1707 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1708 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1709 MCOperand &Op = Inst.getOperand(i);
1711 int MemOffset = Op.getImm();
1712 if (MemOffset < -32768 || MemOffset > 32767) {
1713 // Offset can't exceed 16bit value.
1714 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1717 } else if (Op.isExpr()) {
1718 const MCExpr *Expr = Op.getExpr();
1719 if (Expr->getKind() == MCExpr::SymbolRef) {
1720 const MCSymbolRefExpr *SR =
1721 static_cast<const MCSymbolRefExpr *>(Expr);
1722 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1724 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1727 } else if (!isEvaluated(Expr)) {
1728 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1736 if (inMicroMipsMode()) {
1737 if (MCID.mayLoad()) {
1738 // Try to create 16-bit GP relative load instruction.
1739 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1740 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1741 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1742 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1743 MCOperand &Op = Inst.getOperand(i);
1745 int MemOffset = Op.getImm();
1746 MCOperand &DstReg = Inst.getOperand(0);
1747 MCOperand &BaseReg = Inst.getOperand(1);
1748 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1749 getContext().getRegisterInfo()->getRegClass(
1750 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1751 (BaseReg.getReg() == Mips::GP ||
1752 BaseReg.getReg() == Mips::GP_64)) {
1754 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1755 IDLoc, Instructions);
1763 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1768 switch (Inst.getOpcode()) {
1771 case Mips::ADDIUS5_MM:
1772 Opnd = Inst.getOperand(2);
1774 return Error(IDLoc, "expected immediate operand kind");
1775 Imm = Opnd.getImm();
1776 if (Imm < -8 || Imm > 7)
1777 return Error(IDLoc, "immediate operand value out of range");
1779 case Mips::ADDIUSP_MM:
1780 Opnd = Inst.getOperand(0);
1782 return Error(IDLoc, "expected immediate operand kind");
1783 Imm = Opnd.getImm();
1784 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1786 return Error(IDLoc, "immediate operand value out of range");
1788 case Mips::SLL16_MM:
1789 case Mips::SRL16_MM:
1790 Opnd = Inst.getOperand(2);
1792 return Error(IDLoc, "expected immediate operand kind");
1793 Imm = Opnd.getImm();
1794 if (Imm < 1 || Imm > 8)
1795 return Error(IDLoc, "immediate operand value out of range");
1798 Opnd = Inst.getOperand(1);
1800 return Error(IDLoc, "expected immediate operand kind");
1801 Imm = Opnd.getImm();
1802 if (Imm < -1 || Imm > 126)
1803 return Error(IDLoc, "immediate operand value out of range");
1805 case Mips::ADDIUR2_MM:
1806 Opnd = Inst.getOperand(2);
1808 return Error(IDLoc, "expected immediate operand kind");
1809 Imm = Opnd.getImm();
1810 if (!(Imm == 1 || Imm == -1 ||
1811 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1812 return Error(IDLoc, "immediate operand value out of range");
1814 case Mips::ADDIUR1SP_MM:
1815 Opnd = Inst.getOperand(1);
1817 return Error(IDLoc, "expected immediate operand kind");
1818 Imm = Opnd.getImm();
1819 if (OffsetToAlignment(Imm, 4LL))
1820 return Error(IDLoc, "misaligned immediate operand value");
1821 if (Imm < 0 || Imm > 255)
1822 return Error(IDLoc, "immediate operand value out of range");
1824 case Mips::ANDI16_MM:
1825 Opnd = Inst.getOperand(2);
1827 return Error(IDLoc, "expected immediate operand kind");
1828 Imm = Opnd.getImm();
1829 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1830 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1831 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1832 return Error(IDLoc, "immediate operand value out of range");
1834 case Mips::LBU16_MM:
1835 Opnd = Inst.getOperand(2);
1837 return Error(IDLoc, "expected immediate operand kind");
1838 Imm = Opnd.getImm();
1839 if (Imm < -1 || Imm > 14)
1840 return Error(IDLoc, "immediate operand value out of range");
1849 case Mips::SB16_MMR6:
1850 Opnd = Inst.getOperand(2);
1852 return Error(IDLoc, "expected immediate operand kind");
1853 Imm = Opnd.getImm();
1854 if (Imm < 0 || Imm > 15)
1855 return Error(IDLoc, "immediate operand value out of range");
1857 case Mips::LHU16_MM:
1859 case Mips::SH16_MMR6:
1860 Opnd = Inst.getOperand(2);
1862 return Error(IDLoc, "expected immediate operand kind");
1863 Imm = Opnd.getImm();
1864 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1865 return Error(IDLoc, "immediate operand value out of range");
1869 case Mips::SW16_MMR6:
1870 Opnd = Inst.getOperand(2);
1872 return Error(IDLoc, "expected immediate operand kind");
1873 Imm = Opnd.getImm();
1874 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1875 return Error(IDLoc, "immediate operand value out of range");
1877 case Mips::PREFX_MM:
1880 Opnd = Inst.getOperand(2);
1882 return Error(IDLoc, "expected immediate operand kind");
1883 Imm = Opnd.getImm();
1884 if (!isUInt<5>(Imm))
1885 return Error(IDLoc, "immediate operand value out of range");
1887 case Mips::ADDIUPC_MM:
1888 MCOperand Opnd = Inst.getOperand(1);
1890 return Error(IDLoc, "expected immediate operand kind");
1891 int Imm = Opnd.getImm();
1892 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1893 return Error(IDLoc, "immediate operand value out of range");
1898 MacroExpanderResultTy ExpandResult =
1899 tryExpandInstruction(Inst, IDLoc, Instructions);
1900 switch (ExpandResult) {
1902 Instructions.push_back(Inst);
1910 // If this instruction has a delay slot and .set reorder is active,
1911 // emit a NOP after it.
1912 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1913 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1915 if ((Inst.getOpcode() == Mips::JalOneReg ||
1916 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1917 isPicAndNotNxxAbi()) {
1918 if (IsCpRestoreSet) {
1919 // We need a NOP between the JALR and the LW:
1920 // If .set reorder has been used, we've already emitted a NOP.
1921 // If .set noreorder has been used, we need to emit a NOP at this point.
1922 if (!AssemblerOptions.back()->isReorder())
1923 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1925 // Load the $gp from the stack.
1926 SmallVector<MCInst, 3> LoadInsts;
1927 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1930 for (const MCInst &Inst : LoadInsts)
1931 Instructions.push_back(Inst);
1934 Warning(IDLoc, "no .cprestore used in PIC mode");
1940 MipsAsmParser::MacroExpanderResultTy
1941 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
1942 SmallVectorImpl<MCInst> &Instructions) {
1943 switch (Inst.getOpcode()) {
1945 return MER_NotAMacro;
1946 case Mips::LoadImm32:
1947 return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
1949 case Mips::LoadImm64:
1950 return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
1952 case Mips::LoadAddrImm32:
1953 case Mips::LoadAddrImm64:
1954 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1955 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1956 "expected immediate operand kind");
1958 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
1960 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1964 case Mips::LoadAddrReg32:
1965 case Mips::LoadAddrReg64:
1966 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1967 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1968 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1969 "expected immediate operand kind");
1971 return expandLoadAddress(Inst.getOperand(0).getReg(),
1972 Inst.getOperand(1).getReg(), Inst.getOperand(2),
1973 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
1977 case Mips::B_MM_Pseudo:
1978 case Mips::B_MMR6_Pseudo:
1979 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
1983 return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
1985 case Mips::JalOneReg:
1986 case Mips::JalTwoReg:
1987 return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
1991 return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2008 case Mips::BLTImmMacro:
2009 case Mips::BLEImmMacro:
2010 case Mips::BGEImmMacro:
2011 case Mips::BGTImmMacro:
2012 case Mips::BLTUImmMacro:
2013 case Mips::BLEUImmMacro:
2014 case Mips::BGEUImmMacro:
2015 case Mips::BGTUImmMacro:
2016 case Mips::BLTLImmMacro:
2017 case Mips::BLELImmMacro:
2018 case Mips::BGELImmMacro:
2019 case Mips::BGTLImmMacro:
2020 case Mips::BLTULImmMacro:
2021 case Mips::BLEULImmMacro:
2022 case Mips::BGEULImmMacro:
2023 case Mips::BGTULImmMacro:
2024 return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2026 case Mips::SDivMacro:
2027 return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2029 case Mips::DSDivMacro:
2030 return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2032 case Mips::UDivMacro:
2033 return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2035 case Mips::DUDivMacro:
2036 return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2039 return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2041 return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2043 return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2045 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2051 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2052 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2053 int64_t ImmValue = Inst.getOperand(2).getImm();
2054 if (isInt<16>(ImmValue))
2055 return MER_NotAMacro;
2056 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2059 return MER_NotAMacro;
2063 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2064 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2065 int64_t ImmValue = Inst.getOperand(2).getImm();
2066 if (isUInt<16>(ImmValue))
2067 return MER_NotAMacro;
2068 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2071 return MER_NotAMacro;
2075 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2076 SmallVectorImpl<MCInst> &Instructions) {
2077 // Create a JALR instruction which is going to replace the pseudo-JAL.
2079 JalrInst.setLoc(IDLoc);
2080 const MCOperand FirstRegOp = Inst.getOperand(0);
2081 const unsigned Opcode = Inst.getOpcode();
2083 if (Opcode == Mips::JalOneReg) {
2084 // jal $rs => jalr $rs
2085 if (IsCpRestoreSet && inMicroMipsMode()) {
2086 JalrInst.setOpcode(Mips::JALRS16_MM);
2087 JalrInst.addOperand(FirstRegOp);
2088 } else if (inMicroMipsMode()) {
2089 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2090 JalrInst.addOperand(FirstRegOp);
2092 JalrInst.setOpcode(Mips::JALR);
2093 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2094 JalrInst.addOperand(FirstRegOp);
2096 } else if (Opcode == Mips::JalTwoReg) {
2097 // jal $rd, $rs => jalr $rd, $rs
2098 if (IsCpRestoreSet && inMicroMipsMode())
2099 JalrInst.setOpcode(Mips::JALRS_MM);
2101 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2102 JalrInst.addOperand(FirstRegOp);
2103 const MCOperand SecondRegOp = Inst.getOperand(1);
2104 JalrInst.addOperand(SecondRegOp);
2106 Instructions.push_back(JalrInst);
2108 // If .set reorder is active and branch instruction has a delay slot,
2109 // emit a NOP after it.
2110 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2111 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2112 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2118 /// Can the value be represented by a unsigned N-bit value and a shift left?
2119 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2120 unsigned BitNum = findFirstSet(x);
2122 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2125 /// Load (or add) an immediate into a register.
2127 /// @param ImmValue The immediate to load.
2128 /// @param DstReg The register that will hold the immediate.
2129 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2130 /// for a simple initialization.
2131 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2132 /// @param IsAddress True if the immediate represents an address. False if it
2134 /// @param IDLoc Location of the immediate in the source file.
2135 /// @param Instructions The instructions emitted by this expansion.
2136 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2137 unsigned SrcReg, bool Is32BitImm,
2138 bool IsAddress, SMLoc IDLoc,
2139 SmallVectorImpl<MCInst> &Instructions) {
2140 if (!Is32BitImm && !isGP64bit()) {
2141 Error(IDLoc, "instruction requires a 64-bit architecture");
2146 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2147 // Sign extend up to 64-bit so that the predicates match the hardware
2148 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2150 ImmValue = SignExtend64<32>(ImmValue);
2152 Error(IDLoc, "instruction requires a 32-bit immediate");
2157 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2158 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2160 bool UseSrcReg = false;
2161 if (SrcReg != Mips::NoRegister)
2164 unsigned TmpReg = DstReg;
2165 if (UseSrcReg && (DstReg == SrcReg)) {
2166 // At this point we need AT to perform the expansions and we exit if it is
2168 unsigned ATReg = getATReg(IDLoc);
2174 if (isInt<16>(ImmValue)) {
2178 // This doesn't quite follow the usual ABI expectations for N32 but matches
2179 // traditional assembler behaviour. N32 would normally use addiu for both
2180 // integers and addresses.
2181 if (IsAddress && !Is32BitImm) {
2182 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2186 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2190 if (isUInt<16>(ImmValue)) {
2191 unsigned TmpReg = DstReg;
2192 if (SrcReg == DstReg) {
2193 TmpReg = getATReg(IDLoc);
2198 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2200 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2204 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2205 warnIfNoMacro(IDLoc);
2207 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2208 uint16_t Bits15To0 = ImmValue & 0xffff;
2210 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2211 // Traditional behaviour seems to special case this particular value. It's
2212 // not clear why other masks are handled differently.
2213 if (ImmValue == 0xffffffff) {
2214 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2215 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2217 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2221 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2223 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2224 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2226 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2228 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2232 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2234 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2236 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2240 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2242 Error(IDLoc, "instruction requires a 32-bit immediate");
2246 // Traditionally, these immediates are shifted as little as possible and as
2247 // such we align the most significant bit to bit 15 of our temporary.
2248 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2249 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2250 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2251 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2252 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2253 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2256 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2261 warnIfNoMacro(IDLoc);
2263 // The remaining case is packed with a sequence of dsll and ori with zeros
2264 // being omitted and any neighbouring dsll's being coalesced.
2265 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2267 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2268 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2269 IDLoc, Instructions))
2272 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2273 // skip it and defer the shift to the next chunk.
2274 unsigned ShiftCarriedForwards = 16;
2275 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2276 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2278 if (ImmChunk != 0) {
2279 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2281 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2282 ShiftCarriedForwards = 0;
2285 ShiftCarriedForwards += 16;
2287 ShiftCarriedForwards -= 16;
2289 // Finish any remaining shifts left by trailing zeros.
2290 if (ShiftCarriedForwards)
2291 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2295 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2300 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2301 SmallVectorImpl<MCInst> &Instructions) {
2302 const MCOperand &ImmOp = Inst.getOperand(1);
2303 assert(ImmOp.isImm() && "expected immediate operand kind");
2304 const MCOperand &DstRegOp = Inst.getOperand(0);
2305 assert(DstRegOp.isReg() && "expected register operand kind");
2307 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2308 Is32BitImm, false, IDLoc, Instructions))
2314 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2315 const MCOperand &Offset,
2316 bool Is32BitAddress, SMLoc IDLoc,
2317 SmallVectorImpl<MCInst> &Instructions) {
2318 // la can't produce a usable address when addresses are 64-bit.
2319 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2320 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2321 // We currently can't do this because we depend on the equality
2322 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2323 Error(IDLoc, "la used to load 64-bit address");
2324 // Continue as if we had 'dla' instead.
2325 Is32BitAddress = false;
2328 // dla requires 64-bit addresses.
2329 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2330 Error(IDLoc, "instruction requires a 64-bit architecture");
2334 if (!Offset.isImm())
2335 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2336 Is32BitAddress, IDLoc, Instructions);
2338 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2339 IDLoc, Instructions);
2342 bool MipsAsmParser::loadAndAddSymbolAddress(
2343 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2344 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2345 warnIfNoMacro(IDLoc);
2347 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2348 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2349 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2350 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2351 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2353 bool UseSrcReg = SrcReg != Mips::NoRegister;
2355 // This is the 64-bit symbol address expansion.
2356 if (ABI.ArePtrs64bit() && isGP64bit()) {
2357 // We always need AT for the 64-bit expansion.
2358 // If it is not available we exit.
2359 unsigned ATReg = getATReg(IDLoc);
2363 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2364 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2365 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2366 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2368 if (UseSrcReg && (DstReg == SrcReg)) {
2369 // If $rs is the same as $rd:
2370 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2371 // daddiu $at, $at, %higher(sym)
2372 // dsll $at, $at, 16
2373 // daddiu $at, $at, %hi(sym)
2374 // dsll $at, $at, 16
2375 // daddiu $at, $at, %lo(sym)
2376 // daddu $rd, $at, $rd
2377 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2379 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2380 IDLoc, Instructions);
2381 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2382 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2384 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2385 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2387 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2392 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2393 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2394 // lui $at, %hi(sym)
2395 // daddiu $rd, $rd, %higher(sym)
2396 // daddiu $at, $at, %lo(sym)
2397 // dsll32 $rd, $rd, 0
2398 // daddu $rd, $rd, $at
2399 // (daddu $rd, $rd, $rs)
2400 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2402 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2404 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2405 IDLoc, Instructions);
2406 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2408 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2409 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2411 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2416 // And now, the 32-bit symbol address expansion:
2417 // If $rs is the same as $rd:
2418 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2419 // ori $at, $at, %lo(sym)
2420 // addu $rd, $at, $rd
2421 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2422 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2423 // ori $rd, $rd, %lo(sym)
2424 // (addu $rd, $rd, $rs)
2425 unsigned TmpReg = DstReg;
2426 if (UseSrcReg && (DstReg == SrcReg)) {
2427 // If $rs is the same as $rd, we need to use AT.
2428 // If it is not available we exit.
2429 unsigned ATReg = getATReg(IDLoc);
2435 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2436 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2440 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2442 assert(DstReg == TmpReg);
2447 bool MipsAsmParser::expandUncondBranchMMPseudo(
2448 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2449 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2450 "unexpected number of operands");
2452 MCOperand Offset = Inst.getOperand(0);
2453 if (Offset.isExpr()) {
2455 Inst.setOpcode(Mips::BEQ_MM);
2456 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2457 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2458 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2460 assert(Offset.isImm() && "expected immediate operand kind");
2461 if (isInt<11>(Offset.getImm())) {
2462 // If offset fits into 11 bits then this instruction becomes microMIPS
2463 // 16-bit unconditional branch instruction.
2464 if (inMicroMipsMode())
2465 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2467 if (!isInt<17>(Offset.getImm()))
2468 Error(IDLoc, "branch target out of range");
2469 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2470 Error(IDLoc, "branch to misaligned address");
2472 Inst.setOpcode(Mips::BEQ_MM);
2473 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2474 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2475 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2478 Instructions.push_back(Inst);
2480 // If .set reorder is active and branch instruction has a delay slot,
2481 // emit a NOP after it.
2482 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2483 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2484 createNop(true, IDLoc, Instructions);
2489 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2490 SmallVectorImpl<MCInst> &Instructions) {
2491 const MCOperand &DstRegOp = Inst.getOperand(0);
2492 assert(DstRegOp.isReg() && "expected register operand kind");
2494 const MCOperand &ImmOp = Inst.getOperand(1);
2495 assert(ImmOp.isImm() && "expected immediate operand kind");
2497 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2498 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2500 unsigned OpCode = 0;
2501 switch(Inst.getOpcode()) {
2509 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2513 int64_t ImmValue = ImmOp.getImm();
2515 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2518 warnIfNoMacro(IDLoc);
2520 unsigned ATReg = getATReg(IDLoc);
2524 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2525 IDLoc, Instructions))
2528 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2533 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2534 SmallVectorImpl<MCInst> &Instructions,
2535 bool isLoad, bool isImmOpnd) {
2536 unsigned ImmOffset, HiOffset, LoOffset;
2537 const MCExpr *ExprOffset;
2539 // 1st operand is either the source or destination register.
2540 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2541 unsigned RegOpNum = Inst.getOperand(0).getReg();
2542 // 2nd operand is the base register.
2543 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2544 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2545 // 3rd operand is either an immediate or expression.
2547 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2548 ImmOffset = Inst.getOperand(2).getImm();
2549 LoOffset = ImmOffset & 0x0000ffff;
2550 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2551 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2552 if (LoOffset & 0x8000)
2555 ExprOffset = Inst.getOperand(2).getExpr();
2556 // These are some of the types of expansions we perform here:
2557 // 1) lw $8, sym => lui $8, %hi(sym)
2558 // lw $8, %lo(sym)($8)
2559 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2561 // lw $8, %lo(offset)($9)
2562 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2564 // lw $8, %lo(offset)($at)
2565 // 4) sw $8, sym => lui $at, %hi(sym)
2566 // sw $8, %lo(sym)($at)
2567 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2569 // sw $8, %lo(offset)($at)
2570 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2571 // ldc1 $f0, %lo(sym)($at)
2573 // For load instructions we can use the destination register as a temporary
2574 // if base and dst are different (examples 1 and 2) and if the base register
2575 // is general purpose otherwise we must use $at (example 6) and error if it's
2576 // not available. For stores we must use $at (examples 4 and 5) because we
2577 // must not clobber the source register setting up the offset.
2578 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2579 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2580 unsigned RegClassIDOp0 =
2581 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2582 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2583 (RegClassIDOp0 == Mips::GPR64RegClassID);
2584 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2585 TmpRegNum = RegOpNum;
2587 // At this point we need AT to perform the expansions and we exit if it is
2589 TmpRegNum = getATReg(IDLoc);
2594 emitRX(Mips::LUi, TmpRegNum,
2595 isImmOpnd ? MCOperand::createImm(HiOffset)
2596 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2597 IDLoc, Instructions);
2598 // Add temp register to base.
2599 if (BaseRegNum != Mips::ZERO)
2600 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2601 // And finally, create original instruction with low part
2602 // of offset and new base.
2603 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2605 ? MCOperand::createImm(LoOffset)
2606 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2607 IDLoc, Instructions);
2611 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2612 SmallVectorImpl<MCInst> &Instructions) {
2613 unsigned OpNum = Inst.getNumOperands();
2614 unsigned Opcode = Inst.getOpcode();
2615 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2617 assert (Inst.getOperand(OpNum - 1).isImm() &&
2618 Inst.getOperand(OpNum - 2).isReg() &&
2619 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2621 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2622 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2623 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2624 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2625 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2626 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2627 // It can be implemented as SWM16 or LWM16 instruction.
2628 if (inMicroMipsMode() && hasMips32r6())
2629 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2631 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2634 Inst.setOpcode(NewOpcode);
2635 Instructions.push_back(Inst);
2639 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2640 SmallVectorImpl<MCInst> &Instructions) {
2641 bool EmittedNoMacroWarning = false;
2642 unsigned PseudoOpcode = Inst.getOpcode();
2643 unsigned SrcReg = Inst.getOperand(0).getReg();
2644 const MCOperand &TrgOp = Inst.getOperand(1);
2645 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2647 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2648 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2652 TrgReg = TrgOp.getReg();
2653 else if (TrgOp.isImm()) {
2654 warnIfNoMacro(IDLoc);
2655 EmittedNoMacroWarning = true;
2657 TrgReg = getATReg(IDLoc);
2661 switch(PseudoOpcode) {
2663 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2664 case Mips::BLTImmMacro:
2665 PseudoOpcode = Mips::BLT;
2667 case Mips::BLEImmMacro:
2668 PseudoOpcode = Mips::BLE;
2670 case Mips::BGEImmMacro:
2671 PseudoOpcode = Mips::BGE;
2673 case Mips::BGTImmMacro:
2674 PseudoOpcode = Mips::BGT;
2676 case Mips::BLTUImmMacro:
2677 PseudoOpcode = Mips::BLTU;
2679 case Mips::BLEUImmMacro:
2680 PseudoOpcode = Mips::BLEU;
2682 case Mips::BGEUImmMacro:
2683 PseudoOpcode = Mips::BGEU;
2685 case Mips::BGTUImmMacro:
2686 PseudoOpcode = Mips::BGTU;
2688 case Mips::BLTLImmMacro:
2689 PseudoOpcode = Mips::BLTL;
2691 case Mips::BLELImmMacro:
2692 PseudoOpcode = Mips::BLEL;
2694 case Mips::BGELImmMacro:
2695 PseudoOpcode = Mips::BGEL;
2697 case Mips::BGTLImmMacro:
2698 PseudoOpcode = Mips::BGTL;
2700 case Mips::BLTULImmMacro:
2701 PseudoOpcode = Mips::BLTUL;
2703 case Mips::BLEULImmMacro:
2704 PseudoOpcode = Mips::BLEUL;
2706 case Mips::BGEULImmMacro:
2707 PseudoOpcode = Mips::BGEUL;
2709 case Mips::BGTULImmMacro:
2710 PseudoOpcode = Mips::BGTUL;
2714 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2715 false, IDLoc, Instructions))
2719 switch (PseudoOpcode) {
2724 AcceptsEquality = false;
2725 ReverseOrderSLT = false;
2726 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2727 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2728 ZeroSrcOpcode = Mips::BGTZ;
2729 ZeroTrgOpcode = Mips::BLTZ;
2735 AcceptsEquality = true;
2736 ReverseOrderSLT = true;
2737 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2738 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2739 ZeroSrcOpcode = Mips::BGEZ;
2740 ZeroTrgOpcode = Mips::BLEZ;
2746 AcceptsEquality = true;
2747 ReverseOrderSLT = false;
2748 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2749 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2750 ZeroSrcOpcode = Mips::BLEZ;
2751 ZeroTrgOpcode = Mips::BGEZ;
2757 AcceptsEquality = false;
2758 ReverseOrderSLT = true;
2759 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2760 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2761 ZeroSrcOpcode = Mips::BLTZ;
2762 ZeroTrgOpcode = Mips::BGTZ;
2765 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2768 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2769 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2770 if (IsSrcRegZero && IsTrgRegZero) {
2771 // FIXME: All of these Opcode-specific if's are needed for compatibility
2772 // with GAS' behaviour. However, they may not generate the most efficient
2773 // code in some circumstances.
2774 if (PseudoOpcode == Mips::BLT) {
2775 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2779 if (PseudoOpcode == Mips::BLE) {
2780 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2782 Warning(IDLoc, "branch is always taken");
2785 if (PseudoOpcode == Mips::BGE) {
2786 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2788 Warning(IDLoc, "branch is always taken");
2791 if (PseudoOpcode == Mips::BGT) {
2792 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2796 if (PseudoOpcode == Mips::BGTU) {
2797 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2798 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2801 if (AcceptsEquality) {
2802 // If both registers are $0 and the pseudo-branch accepts equality, it
2803 // will always be taken, so we emit an unconditional branch.
2804 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2805 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2806 Warning(IDLoc, "branch is always taken");
2809 // If both registers are $0 and the pseudo-branch does not accept
2810 // equality, it will never be taken, so we don't have to emit anything.
2813 if (IsSrcRegZero || IsTrgRegZero) {
2814 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2815 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2816 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2817 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2818 // the pseudo-branch will never be taken, so we don't emit anything.
2819 // This only applies to unsigned pseudo-branches.
2822 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2823 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2824 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2825 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2826 // the pseudo-branch will always be taken, so we emit an unconditional
2828 // This only applies to unsigned pseudo-branches.
2829 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2830 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2831 Warning(IDLoc, "branch is always taken");
2835 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2836 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2837 // the pseudo-branch will be taken only when the non-zero register is
2838 // different from 0, so we emit a BNEZ.
2840 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2841 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2842 // the pseudo-branch will be taken only when the non-zero register is
2843 // equal to 0, so we emit a BEQZ.
2845 // Because only BLEU and BGEU branch on equality, we can use the
2846 // AcceptsEquality variable to decide when to emit the BEQZ.
2847 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2848 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2849 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2852 // If we have a signed pseudo-branch and one of the registers is $0,
2853 // we can use an appropriate compare-to-zero branch. We select which one
2854 // to use in the switch statement above.
2855 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2856 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2857 IDLoc, Instructions);
2861 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2862 // expansions. If it is not available, we return.
2863 unsigned ATRegNum = getATReg(IDLoc);
2867 if (!EmittedNoMacroWarning)
2868 warnIfNoMacro(IDLoc);
2870 // SLT fits well with 2 of our 4 pseudo-branches:
2871 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2872 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2873 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2874 // This is accomplished by using a BNEZ with the result of the SLT.
2876 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2877 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2878 // Because only BGE and BLE branch on equality, we can use the
2879 // AcceptsEquality variable to decide when to emit the BEQZ.
2880 // Note that the order of the SLT arguments doesn't change between
2883 // The same applies to the unsigned variants, except that SLTu is used
2885 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2886 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2887 IDLoc, Instructions);
2889 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2890 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2891 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2896 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2897 SmallVectorImpl<MCInst> &Instructions,
2898 const bool IsMips64, const bool Signed) {
2899 if (hasMips32r6()) {
2900 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2904 warnIfNoMacro(IDLoc);
2906 const MCOperand &RsRegOp = Inst.getOperand(0);
2907 assert(RsRegOp.isReg() && "expected register operand kind");
2908 unsigned RsReg = RsRegOp.getReg();
2910 const MCOperand &RtRegOp = Inst.getOperand(1);
2911 assert(RtRegOp.isReg() && "expected register operand kind");
2912 unsigned RtReg = RtRegOp.getReg();
2917 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2918 ZeroReg = Mips::ZERO_64;
2920 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2921 ZeroReg = Mips::ZERO;
2924 bool UseTraps = useTraps();
2926 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2927 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2928 Warning(IDLoc, "dividing zero by zero");
2930 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2932 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2936 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2940 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2945 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2946 Warning(IDLoc, "division by zero");
2949 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2953 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2958 // FIXME: The values for these two BranchTarget variables may be different in
2959 // micromips. These magic numbers need to be removed.
2960 unsigned BranchTargetNoTraps;
2961 unsigned BranchTarget;
2964 BranchTarget = IsMips64 ? 12 : 8;
2965 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2967 BranchTarget = IsMips64 ? 20 : 16;
2968 BranchTargetNoTraps = 8;
2969 // Branch to the li instruction.
2970 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2974 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2977 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2980 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2984 unsigned ATReg = getATReg(IDLoc);
2988 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2990 // Branch to the mflo instruction.
2991 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2992 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2993 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2995 // Branch to the mflo instruction.
2996 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2997 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
3001 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
3003 // Branch to the mflo instruction.
3004 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
3005 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
3006 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
3008 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3012 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3013 SmallVectorImpl<MCInst> &Instructions) {
3014 if (hasMips32r6() || hasMips64r6()) {
3015 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3019 warnIfNoMacro(IDLoc);
3021 const MCOperand &DstRegOp = Inst.getOperand(0);
3022 assert(DstRegOp.isReg() && "expected register operand kind");
3024 const MCOperand &SrcRegOp = Inst.getOperand(1);
3025 assert(SrcRegOp.isReg() && "expected register operand kind");
3027 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3028 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3030 unsigned DstReg = DstRegOp.getReg();
3031 unsigned SrcReg = SrcRegOp.getReg();
3032 int64_t OffsetValue = OffsetImmOp.getImm();
3034 // NOTE: We always need AT for ULHU, as it is always used as the source
3035 // register for one of the LBu's.
3036 unsigned ATReg = getATReg(IDLoc);
3040 // When the value of offset+1 does not fit in 16 bits, we have to load the
3041 // offset in AT, (D)ADDu the original source register (if there was one), and
3042 // then use AT as the source register for the 2 generated LBu's.
3043 bool LoadedOffsetInAT = false;
3044 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3045 LoadedOffsetInAT = true;
3047 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3048 true, IDLoc, Instructions))
3051 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3052 // because it will make our output more similar to GAS'. For example,
3053 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3054 // instead of just an "ori $1, $9, 32768".
3055 // NOTE: If there is no source register specified in the ULHU, the parser
3056 // will interpret it as $0.
3057 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3058 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3061 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3062 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3063 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3065 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3067 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3068 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3070 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3071 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3074 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3076 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3077 FirstLbuOffset, IDLoc, Instructions);
3079 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3082 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3084 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3089 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3090 SmallVectorImpl<MCInst> &Instructions) {
3091 if (hasMips32r6() || hasMips64r6()) {
3092 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3096 const MCOperand &DstRegOp = Inst.getOperand(0);
3097 assert(DstRegOp.isReg() && "expected register operand kind");
3099 const MCOperand &SrcRegOp = Inst.getOperand(1);
3100 assert(SrcRegOp.isReg() && "expected register operand kind");
3102 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3103 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3105 unsigned SrcReg = SrcRegOp.getReg();
3106 int64_t OffsetValue = OffsetImmOp.getImm();
3109 // When the value of offset+3 does not fit in 16 bits, we have to load the
3110 // offset in AT, (D)ADDu the original source register (if there was one), and
3111 // then use AT as the source register for the generated LWL and LWR.
3112 bool LoadedOffsetInAT = false;
3113 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3114 ATReg = getATReg(IDLoc);
3117 LoadedOffsetInAT = true;
3119 warnIfNoMacro(IDLoc);
3121 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3122 true, IDLoc, Instructions))
3125 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3126 // because it will make our output more similar to GAS'. For example,
3127 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3128 // instead of just an "ori $1, $9, 32768".
3129 // NOTE: If there is no source register specified in the ULW, the parser
3130 // will interpret it as $0.
3131 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3132 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3135 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3136 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3138 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3139 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3141 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3142 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3145 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3148 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3154 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3155 SmallVectorImpl<MCInst> &Instructions) {
3157 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3158 assert (Inst.getOperand(0).isReg() &&
3159 Inst.getOperand(1).isReg() &&
3160 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3162 unsigned ATReg = Mips::NoRegister;
3163 unsigned FinalDstReg = Mips::NoRegister;
3164 unsigned DstReg = Inst.getOperand(0).getReg();
3165 unsigned SrcReg = Inst.getOperand(1).getReg();
3166 int64_t ImmValue = Inst.getOperand(2).getImm();
3168 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3170 unsigned FinalOpcode = Inst.getOpcode();
3172 if (DstReg == SrcReg) {
3173 ATReg = getATReg(Inst.getLoc());
3176 FinalDstReg = DstReg;
3180 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3181 switch (FinalOpcode) {
3183 llvm_unreachable("unimplemented expansion");
3185 FinalOpcode = Mips::ADD;
3188 FinalOpcode = Mips::ADDu;
3191 FinalOpcode = Mips::AND;
3193 case (Mips::NORImm):
3194 FinalOpcode = Mips::NOR;
3197 FinalOpcode = Mips::OR;
3200 FinalOpcode = Mips::SLT;
3203 FinalOpcode = Mips::SLTu;
3206 FinalOpcode = Mips::XOR;
3210 if (FinalDstReg == Mips::NoRegister)
3211 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3213 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3220 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3221 SmallVectorImpl<MCInst> &Instructions) {
3222 if (hasShortDelaySlot)
3223 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3225 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3228 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3229 unsigned TrgReg, bool Is64Bit,
3230 SmallVectorImpl<MCInst> &Instructions) {
3231 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3235 void MipsAsmParser::createCpRestoreMemOp(
3236 bool IsLoad, int StackOffset, SMLoc IDLoc,
3237 SmallVectorImpl<MCInst> &Instructions) {
3238 // If the offset can not fit into 16 bits, we need to expand.
3239 if (!isInt<16>(StackOffset)) {
3241 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3242 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3243 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3244 MemInst.addOperand(MCOperand::createImm(StackOffset));
3245 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3249 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3253 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3254 // As described by the Mips32r2 spec, the registers Rd and Rs for
3255 // jalr.hb must be different.
3256 unsigned Opcode = Inst.getOpcode();
3258 if (Opcode == Mips::JALR_HB &&
3259 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3260 return Match_RequiresDifferentSrcAndDst;
3262 return Match_Success;
3265 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3266 uint64_t ErrorInfo) {
3267 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3268 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3269 if (ErrorLoc == SMLoc())
3276 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3277 OperandVector &Operands,
3279 uint64_t &ErrorInfo,
3280 bool MatchingInlineAsm) {
3283 SmallVector<MCInst, 8> Instructions;
3284 unsigned MatchResult =
3285 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3287 switch (MatchResult) {
3288 case Match_Success: {
3289 if (processInstruction(Inst, IDLoc, Instructions))
3291 for (unsigned i = 0; i < Instructions.size(); i++)
3292 Out.EmitInstruction(Instructions[i], STI);
3295 case Match_MissingFeature:
3296 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3298 case Match_InvalidOperand: {
3299 SMLoc ErrorLoc = IDLoc;
3300 if (ErrorInfo != ~0ULL) {
3301 if (ErrorInfo >= Operands.size())
3302 return Error(IDLoc, "too few operands for instruction");
3304 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3305 if (ErrorLoc == SMLoc())
3309 return Error(ErrorLoc, "invalid operand for instruction");
3311 case Match_MnemonicFail:
3312 return Error(IDLoc, "invalid instruction");
3313 case Match_RequiresDifferentSrcAndDst:
3314 return Error(IDLoc, "source and destination must be different");
3316 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3318 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3319 "expected 1-bit unsigned immediate");
3321 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3322 "expected 2-bit unsigned immediate");
3324 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3325 "expected immediate in range 1 .. 4");
3327 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3328 "expected 3-bit unsigned immediate");
3330 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3331 "expected 4-bit unsigned immediate");
3334 llvm_unreachable("Implement any new match types added!");
3337 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3338 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3339 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3340 ") without \".set noat\"");
3343 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3344 if (!AssemblerOptions.back()->isMacro())
3345 Warning(Loc, "macro instruction expanded into multiple instructions");
3349 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3350 SMRange Range, bool ShowColors) {
3351 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3352 Range, SMFixIt(Range, FixMsg),
3356 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3359 CC = StringSwitch<unsigned>(Name)
3395 if (!(isABI_N32() || isABI_N64()))
3398 if (12 <= CC && CC <= 15) {
3399 // Name is one of t4-t7
3400 AsmToken RegTok = getLexer().peekTok();
3401 SMRange RegRange = RegTok.getLocRange();
3403 StringRef FixedName = StringSwitch<StringRef>(Name)
3409 assert(FixedName != "" && "Register name is not one of t4-t7.");
3411 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3412 "Did you mean $" + FixedName + "?", RegRange);
3415 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3416 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3417 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3418 if (8 <= CC && CC <= 11)
3422 CC = StringSwitch<unsigned>(Name)
3434 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3437 CC = StringSwitch<unsigned>(Name)
3438 .Case("hwr_cpunum", 0)
3439 .Case("hwr_synci_step", 1)
3441 .Case("hwr_ccres", 3)
3442 .Case("hwr_ulr", 29)
3448 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3450 if (Name[0] == 'f') {
3451 StringRef NumString = Name.substr(1);
3453 if (NumString.getAsInteger(10, IntVal))
3454 return -1; // This is not an integer.
3455 if (IntVal > 31) // Maximum index for fpu register.
3462 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3464 if (Name.startswith("fcc")) {
3465 StringRef NumString = Name.substr(3);
3467 if (NumString.getAsInteger(10, IntVal))
3468 return -1; // This is not an integer.
3469 if (IntVal > 7) // There are only 8 fcc registers.
3476 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3478 if (Name.startswith("ac")) {
3479 StringRef NumString = Name.substr(2);
3481 if (NumString.getAsInteger(10, IntVal))
3482 return -1; // This is not an integer.
3483 if (IntVal > 3) // There are only 3 acc registers.
3490 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3493 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3502 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3505 CC = StringSwitch<unsigned>(Name)
3508 .Case("msaaccess", 2)
3510 .Case("msamodify", 4)
3511 .Case("msarequest", 5)
3513 .Case("msaunmap", 7)
3519 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3520 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3522 reportParseError(Loc,
3523 "pseudo-instruction requires $at, which is not available");
3526 unsigned AT = getReg(
3527 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3531 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3532 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3535 unsigned MipsAsmParser::getGPR(int RegNo) {
3536 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3540 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3542 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3545 return getReg(RegClass, RegNum);
3548 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3549 MCAsmParser &Parser = getParser();
3550 DEBUG(dbgs() << "parseOperand\n");
3552 // Check if the current operand has a custom associated parser, if so, try to
3553 // custom parse the operand, or fallback to the general approach.
3554 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3555 if (ResTy == MatchOperand_Success)
3557 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3558 // there was a match, but an error occurred, in which case, just return that
3559 // the operand parsing failed.
3560 if (ResTy == MatchOperand_ParseFail)
3563 DEBUG(dbgs() << ".. Generic Parser\n");
3565 switch (getLexer().getKind()) {
3567 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3569 case AsmToken::Dollar: {
3570 // Parse the register.
3571 SMLoc S = Parser.getTok().getLoc();
3573 // Almost all registers have been parsed by custom parsers. There is only
3574 // one exception to this. $zero (and it's alias $0) will reach this point
3575 // for div, divu, and similar instructions because it is not an operand
3576 // to the instruction definition but an explicit register. Special case
3577 // this situation for now.
3578 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3581 // Maybe it is a symbol reference.
3582 StringRef Identifier;
3583 if (Parser.parseIdentifier(Identifier))
3586 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3587 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3588 // Otherwise create a symbol reference.
3590 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3592 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3595 // Else drop to expression parsing.
3596 case AsmToken::LParen:
3597 case AsmToken::Minus:
3598 case AsmToken::Plus:
3599 case AsmToken::Integer:
3600 case AsmToken::Tilde:
3601 case AsmToken::String: {
3602 DEBUG(dbgs() << ".. generic integer\n");
3603 OperandMatchResultTy ResTy = parseImm(Operands);
3604 return ResTy != MatchOperand_Success;
3606 case AsmToken::Percent: {
3607 // It is a symbol reference or constant expression.
3608 const MCExpr *IdVal;
3609 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3610 if (parseRelocOperand(IdVal))
3613 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3615 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3617 } // case AsmToken::Percent
3618 } // switch(getLexer().getKind())
3622 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3623 StringRef RelocStr) {
3625 // Check the type of the expression.
3626 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3627 // It's a constant, evaluate reloc value.
3629 switch (getVariantKind(RelocStr)) {
3630 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3631 // Get the 1st 16-bits.
3632 Val = MCE->getValue() & 0xffff;
3634 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3635 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3636 // 16 bits being negative.
3637 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3639 case MCSymbolRefExpr::VK_Mips_HIGHER:
3640 // Get the 3rd 16-bits.
3641 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3643 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3644 // Get the 4th 16-bits.
3645 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3648 report_fatal_error("unsupported reloc value");
3650 return MCConstantExpr::create(Val, getContext());
3653 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3654 // It's a symbol, create a symbolic expression from the symbol.
3655 const MCSymbol *Symbol = &MSRE->getSymbol();
3656 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3657 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3661 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3662 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3664 // Try to create target expression.
3665 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3666 return MipsMCExpr::create(VK, Expr, getContext());
3668 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3669 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3670 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3674 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3675 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3676 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3679 // Just return the original expression.
3683 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3685 switch (Expr->getKind()) {
3686 case MCExpr::Constant:
3688 case MCExpr::SymbolRef:
3689 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3690 case MCExpr::Binary:
3691 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3692 if (!isEvaluated(BE->getLHS()))
3694 return isEvaluated(BE->getRHS());
3697 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3698 case MCExpr::Target:
3704 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3705 MCAsmParser &Parser = getParser();
3706 Parser.Lex(); // Eat the % token.
3707 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3708 if (Tok.isNot(AsmToken::Identifier))
3711 std::string Str = Tok.getIdentifier();
3713 Parser.Lex(); // Eat the identifier.
3714 // Now make an expression from the rest of the operand.
3715 const MCExpr *IdVal;
3718 if (getLexer().getKind() == AsmToken::LParen) {
3720 Parser.Lex(); // Eat the '(' token.
3721 if (getLexer().getKind() == AsmToken::Percent) {
3722 Parser.Lex(); // Eat the % token.
3723 const AsmToken &nextTok = Parser.getTok();
3724 if (nextTok.isNot(AsmToken::Identifier))
3727 Str += nextTok.getIdentifier();
3728 Parser.Lex(); // Eat the identifier.
3729 if (getLexer().getKind() != AsmToken::LParen)
3734 if (getParser().parseParenExpression(IdVal, EndLoc))
3737 while (getLexer().getKind() == AsmToken::RParen)
3738 Parser.Lex(); // Eat the ')' token.
3741 return true; // Parenthesis must follow the relocation operand.
3743 Res = evaluateRelocExpr(IdVal, Str);
3747 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3749 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3750 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3751 if (ResTy == MatchOperand_Success) {
3752 assert(Operands.size() == 1);
3753 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3754 StartLoc = Operand.getStartLoc();
3755 EndLoc = Operand.getEndLoc();
3757 // AFAIK, we only support numeric registers and named GPR's in CFI
3759 // Don't worry about eating tokens before failing. Using an unrecognised
3760 // register is a parse error.
3761 if (Operand.isGPRAsmReg()) {
3762 // Resolve to GPR32 or GPR64 appropriately.
3763 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3766 return (RegNo == (unsigned)-1);
3769 assert(Operands.size() == 0);
3770 return (RegNo == (unsigned)-1);
3773 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3774 MCAsmParser &Parser = getParser();
3777 unsigned NumOfLParen = 0;
3779 while (getLexer().getKind() == AsmToken::LParen) {
3784 switch (getLexer().getKind()) {
3787 case AsmToken::Identifier:
3788 case AsmToken::LParen:
3789 case AsmToken::Integer:
3790 case AsmToken::Minus:
3791 case AsmToken::Plus:
3793 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3795 Result = (getParser().parseExpression(Res));
3796 while (getLexer().getKind() == AsmToken::RParen)
3799 case AsmToken::Percent:
3800 Result = parseRelocOperand(Res);
3805 MipsAsmParser::OperandMatchResultTy
3806 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3807 MCAsmParser &Parser = getParser();
3808 DEBUG(dbgs() << "parseMemOperand\n");
3809 const MCExpr *IdVal = nullptr;
3811 bool isParenExpr = false;
3812 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3813 // First operand is the offset.
3814 S = Parser.getTok().getLoc();
3816 if (getLexer().getKind() == AsmToken::LParen) {
3821 if (getLexer().getKind() != AsmToken::Dollar) {
3822 if (parseMemOffset(IdVal, isParenExpr))
3823 return MatchOperand_ParseFail;
3825 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3826 if (Tok.isNot(AsmToken::LParen)) {
3827 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3828 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3830 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3831 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3832 return MatchOperand_Success;
3834 if (Tok.is(AsmToken::EndOfStatement)) {
3836 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3838 // Zero register assumed, add a memory operand with ZERO as its base.
3839 // "Base" will be managed by k_Memory.
3840 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3843 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3844 return MatchOperand_Success;
3846 Error(Parser.getTok().getLoc(), "'(' expected");
3847 return MatchOperand_ParseFail;
3850 Parser.Lex(); // Eat the '(' token.
3853 Res = parseAnyRegister(Operands);
3854 if (Res != MatchOperand_Success)
3857 if (Parser.getTok().isNot(AsmToken::RParen)) {
3858 Error(Parser.getTok().getLoc(), "')' expected");
3859 return MatchOperand_ParseFail;
3862 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3864 Parser.Lex(); // Eat the ')' token.
3867 IdVal = MCConstantExpr::create(0, getContext());
3869 // Replace the register operand with the memory operand.
3870 std::unique_ptr<MipsOperand> op(
3871 static_cast<MipsOperand *>(Operands.back().release()));
3872 // Remove the register from the operands.
3873 // "op" will be managed by k_Memory.
3874 Operands.pop_back();
3875 // Add the memory operand.
3876 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3878 if (IdVal->evaluateAsAbsolute(Imm))
3879 IdVal = MCConstantExpr::create(Imm, getContext());
3880 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3881 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3885 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3886 return MatchOperand_Success;
3889 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3890 MCAsmParser &Parser = getParser();
3891 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3893 SMLoc S = Parser.getTok().getLoc();
3895 if (Sym->isVariable())
3896 Expr = Sym->getVariableValue();
3899 if (Expr->getKind() == MCExpr::SymbolRef) {
3900 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3901 StringRef DefSymbol = Ref->getSymbol().getName();
3902 if (DefSymbol.startswith("$")) {
3903 OperandMatchResultTy ResTy =
3904 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3905 if (ResTy == MatchOperand_Success) {
3908 } else if (ResTy == MatchOperand_ParseFail)
3909 llvm_unreachable("Should never ParseFail");
3912 } else if (Expr->getKind() == MCExpr::Constant) {
3914 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3916 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3923 MipsAsmParser::OperandMatchResultTy
3924 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3925 StringRef Identifier,
3927 int Index = matchCPURegisterName(Identifier);
3929 Operands.push_back(MipsOperand::createGPRReg(
3930 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3931 return MatchOperand_Success;
3934 Index = matchHWRegsRegisterName(Identifier);
3936 Operands.push_back(MipsOperand::createHWRegsReg(
3937 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3938 return MatchOperand_Success;
3941 Index = matchFPURegisterName(Identifier);
3943 Operands.push_back(MipsOperand::createFGRReg(
3944 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3945 return MatchOperand_Success;
3948 Index = matchFCCRegisterName(Identifier);
3950 Operands.push_back(MipsOperand::createFCCReg(
3951 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3952 return MatchOperand_Success;
3955 Index = matchACRegisterName(Identifier);
3957 Operands.push_back(MipsOperand::createACCReg(
3958 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3959 return MatchOperand_Success;
3962 Index = matchMSA128RegisterName(Identifier);
3964 Operands.push_back(MipsOperand::createMSA128Reg(
3965 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3966 return MatchOperand_Success;
3969 Index = matchMSA128CtrlRegisterName(Identifier);
3971 Operands.push_back(MipsOperand::createMSACtrlReg(
3972 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3973 return MatchOperand_Success;
3976 return MatchOperand_NoMatch;
3979 MipsAsmParser::OperandMatchResultTy
3980 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3981 MCAsmParser &Parser = getParser();
3982 auto Token = Parser.getLexer().peekTok(false);
3984 if (Token.is(AsmToken::Identifier)) {
3985 DEBUG(dbgs() << ".. identifier\n");
3986 StringRef Identifier = Token.getIdentifier();
3987 OperandMatchResultTy ResTy =
3988 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3990 } else if (Token.is(AsmToken::Integer)) {
3991 DEBUG(dbgs() << ".. integer\n");
3992 Operands.push_back(MipsOperand::createNumericReg(
3993 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3995 return MatchOperand_Success;
3998 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4000 return MatchOperand_NoMatch;
4003 MipsAsmParser::OperandMatchResultTy
4004 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4005 MCAsmParser &Parser = getParser();
4006 DEBUG(dbgs() << "parseAnyRegister\n");
4008 auto Token = Parser.getTok();
4010 SMLoc S = Token.getLoc();
4012 if (Token.isNot(AsmToken::Dollar)) {
4013 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4014 if (Token.is(AsmToken::Identifier)) {
4015 if (searchSymbolAlias(Operands))
4016 return MatchOperand_Success;
4018 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4019 return MatchOperand_NoMatch;
4021 DEBUG(dbgs() << ".. $\n");
4023 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4024 if (ResTy == MatchOperand_Success) {
4026 Parser.Lex(); // identifier
4031 MipsAsmParser::OperandMatchResultTy
4032 MipsAsmParser::parseImm(OperandVector &Operands) {
4033 MCAsmParser &Parser = getParser();
4034 switch (getLexer().getKind()) {
4036 return MatchOperand_NoMatch;
4037 case AsmToken::LParen:
4038 case AsmToken::Minus:
4039 case AsmToken::Plus:
4040 case AsmToken::Integer:
4041 case AsmToken::Tilde:
4042 case AsmToken::String:
4046 const MCExpr *IdVal;
4047 SMLoc S = Parser.getTok().getLoc();
4048 if (getParser().parseExpression(IdVal))
4049 return MatchOperand_ParseFail;
4051 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4052 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4053 return MatchOperand_Success;
4056 MipsAsmParser::OperandMatchResultTy
4057 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4058 MCAsmParser &Parser = getParser();
4059 DEBUG(dbgs() << "parseJumpTarget\n");
4061 SMLoc S = getLexer().getLoc();
4063 // Integers and expressions are acceptable
4064 OperandMatchResultTy ResTy = parseImm(Operands);
4065 if (ResTy != MatchOperand_NoMatch)
4068 // Registers are a valid target and have priority over symbols.
4069 ResTy = parseAnyRegister(Operands);
4070 if (ResTy != MatchOperand_NoMatch)
4073 const MCExpr *Expr = nullptr;
4074 if (Parser.parseExpression(Expr)) {
4075 // We have no way of knowing if a symbol was consumed so we must ParseFail
4076 return MatchOperand_ParseFail;
4079 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4080 return MatchOperand_Success;
4083 MipsAsmParser::OperandMatchResultTy
4084 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4085 MCAsmParser &Parser = getParser();
4086 const MCExpr *IdVal;
4087 // If the first token is '$' we may have register operand.
4088 if (Parser.getTok().is(AsmToken::Dollar))
4089 return MatchOperand_NoMatch;
4090 SMLoc S = Parser.getTok().getLoc();
4091 if (getParser().parseExpression(IdVal))
4092 return MatchOperand_ParseFail;
4093 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4094 assert(MCE && "Unexpected MCExpr type.");
4095 int64_t Val = MCE->getValue();
4096 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4097 Operands.push_back(MipsOperand::CreateImm(
4098 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4099 return MatchOperand_Success;
4102 MipsAsmParser::OperandMatchResultTy
4103 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4104 MCAsmParser &Parser = getParser();
4105 switch (getLexer().getKind()) {
4107 return MatchOperand_NoMatch;
4108 case AsmToken::LParen:
4109 case AsmToken::Plus:
4110 case AsmToken::Minus:
4111 case AsmToken::Integer:
4116 SMLoc S = Parser.getTok().getLoc();
4118 if (getParser().parseExpression(Expr))
4119 return MatchOperand_ParseFail;
4122 if (!Expr->evaluateAsAbsolute(Val)) {
4123 Error(S, "expected immediate value");
4124 return MatchOperand_ParseFail;
4127 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4128 // and because the CPU always adds one to the immediate field, the allowed
4129 // range becomes 1..4. We'll only check the range here and will deal
4130 // with the addition/subtraction when actually decoding/encoding
4132 if (Val < 1 || Val > 4) {
4133 Error(S, "immediate not in range (1..4)");
4134 return MatchOperand_ParseFail;
4138 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4139 return MatchOperand_Success;
4142 MipsAsmParser::OperandMatchResultTy
4143 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4144 MCAsmParser &Parser = getParser();
4145 SmallVector<unsigned, 10> Regs;
4147 unsigned PrevReg = Mips::NoRegister;
4148 bool RegRange = false;
4149 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4151 if (Parser.getTok().isNot(AsmToken::Dollar))
4152 return MatchOperand_ParseFail;
4154 SMLoc S = Parser.getTok().getLoc();
4155 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4156 SMLoc E = getLexer().getLoc();
4157 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4158 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4160 // Remove last register operand because registers from register range
4161 // should be inserted first.
4162 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4163 (!isGP64bit() && RegNo == Mips::RA)) {
4164 Regs.push_back(RegNo);
4166 unsigned TmpReg = PrevReg + 1;
4167 while (TmpReg <= RegNo) {
4168 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4169 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4171 Error(E, "invalid register operand");
4172 return MatchOperand_ParseFail;
4176 Regs.push_back(TmpReg++);
4182 if ((PrevReg == Mips::NoRegister) &&
4183 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
4184 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
4185 Error(E, "$16 or $31 expected");
4186 return MatchOperand_ParseFail;
4187 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
4188 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
4190 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
4191 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
4193 Error(E, "invalid register operand");
4194 return MatchOperand_ParseFail;
4195 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4196 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
4197 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
4199 Error(E, "consecutive register numbers expected");
4200 return MatchOperand_ParseFail;
4203 Regs.push_back(RegNo);
4206 if (Parser.getTok().is(AsmToken::Minus))
4209 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4210 !Parser.getTok().isNot(AsmToken::Comma)) {
4211 Error(E, "',' or '-' expected");
4212 return MatchOperand_ParseFail;
4215 Lex(); // Consume comma or minus
4216 if (Parser.getTok().isNot(AsmToken::Dollar))
4222 SMLoc E = Parser.getTok().getLoc();
4223 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4224 parseMemOperand(Operands);
4225 return MatchOperand_Success;
4228 MipsAsmParser::OperandMatchResultTy
4229 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4230 MCAsmParser &Parser = getParser();
4232 SMLoc S = Parser.getTok().getLoc();
4233 if (parseAnyRegister(Operands) != MatchOperand_Success)
4234 return MatchOperand_ParseFail;
4236 SMLoc E = Parser.getTok().getLoc();
4237 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4238 unsigned Reg = Op.getGPR32Reg();
4239 Operands.pop_back();
4240 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4241 return MatchOperand_Success;
4244 MipsAsmParser::OperandMatchResultTy
4245 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4246 MCAsmParser &Parser = getParser();
4247 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4248 SmallVector<unsigned, 10> Regs;
4250 if (Parser.getTok().isNot(AsmToken::Dollar))
4251 return MatchOperand_ParseFail;
4253 SMLoc S = Parser.getTok().getLoc();
4255 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4256 return MatchOperand_ParseFail;
4258 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4259 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4260 Regs.push_back(RegNo);
4262 SMLoc E = Parser.getTok().getLoc();
4263 if (Parser.getTok().isNot(AsmToken::Comma)) {
4264 Error(E, "',' expected");
4265 return MatchOperand_ParseFail;
4271 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4272 return MatchOperand_ParseFail;
4274 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4275 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4276 Regs.push_back(RegNo);
4278 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4280 return MatchOperand_Success;
4283 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4285 MCSymbolRefExpr::VariantKind VK =
4286 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4287 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4288 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4289 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4290 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4291 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4292 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4293 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4294 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4295 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4296 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4297 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4298 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4299 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4300 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4301 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4302 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4303 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4304 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4305 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4306 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4307 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4308 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4309 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4310 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4311 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4312 .Default(MCSymbolRefExpr::VK_None);
4314 assert(VK != MCSymbolRefExpr::VK_None);
4319 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4321 /// ::= '(', register, ')'
4322 /// handle it before we iterate so we don't get tripped up by the lack of
4324 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4325 MCAsmParser &Parser = getParser();
4326 if (getLexer().is(AsmToken::LParen)) {
4328 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4330 if (parseOperand(Operands, Name)) {
4331 SMLoc Loc = getLexer().getLoc();
4332 Parser.eatToEndOfStatement();
4333 return Error(Loc, "unexpected token in argument list");
4335 if (Parser.getTok().isNot(AsmToken::RParen)) {
4336 SMLoc Loc = getLexer().getLoc();
4337 Parser.eatToEndOfStatement();
4338 return Error(Loc, "unexpected token, expected ')'");
4341 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4347 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4348 /// either one of these.
4349 /// ::= '[', register, ']'
4350 /// ::= '[', integer, ']'
4351 /// handle it before we iterate so we don't get tripped up by the lack of
4353 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4354 OperandVector &Operands) {
4355 MCAsmParser &Parser = getParser();
4356 if (getLexer().is(AsmToken::LBrac)) {
4358 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4360 if (parseOperand(Operands, Name)) {
4361 SMLoc Loc = getLexer().getLoc();
4362 Parser.eatToEndOfStatement();
4363 return Error(Loc, "unexpected token in argument list");
4365 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4366 SMLoc Loc = getLexer().getLoc();
4367 Parser.eatToEndOfStatement();
4368 return Error(Loc, "unexpected token, expected ']'");
4371 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4377 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4378 SMLoc NameLoc, OperandVector &Operands) {
4379 MCAsmParser &Parser = getParser();
4380 DEBUG(dbgs() << "ParseInstruction\n");
4382 // We have reached first instruction, module directive are now forbidden.
4383 getTargetStreamer().forbidModuleDirective();
4385 // Check if we have valid mnemonic
4386 if (!mnemonicIsValid(Name, 0)) {
4387 Parser.eatToEndOfStatement();
4388 return Error(NameLoc, "unknown instruction");
4390 // First operand in MCInst is instruction mnemonic.
4391 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4393 // Read the remaining operands.
4394 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4395 // Read the first operand.
4396 if (parseOperand(Operands, Name)) {
4397 SMLoc Loc = getLexer().getLoc();
4398 Parser.eatToEndOfStatement();
4399 return Error(Loc, "unexpected token in argument list");
4401 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4403 // AFAIK, parenthesis suffixes are never on the first operand
4405 while (getLexer().is(AsmToken::Comma)) {
4406 Parser.Lex(); // Eat the comma.
4407 // Parse and remember the operand.
4408 if (parseOperand(Operands, Name)) {
4409 SMLoc Loc = getLexer().getLoc();
4410 Parser.eatToEndOfStatement();
4411 return Error(Loc, "unexpected token in argument list");
4413 // Parse bracket and parenthesis suffixes before we iterate
4414 if (getLexer().is(AsmToken::LBrac)) {
4415 if (parseBracketSuffix(Name, Operands))
4417 } else if (getLexer().is(AsmToken::LParen) &&
4418 parseParenSuffix(Name, Operands))
4422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4423 SMLoc Loc = getLexer().getLoc();
4424 Parser.eatToEndOfStatement();
4425 return Error(Loc, "unexpected token in argument list");
4427 Parser.Lex(); // Consume the EndOfStatement.
4431 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4432 MCAsmParser &Parser = getParser();
4433 SMLoc Loc = getLexer().getLoc();
4434 Parser.eatToEndOfStatement();
4435 return Error(Loc, ErrorMsg);
4438 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4439 return Error(Loc, ErrorMsg);
4442 bool MipsAsmParser::parseSetNoAtDirective() {
4443 MCAsmParser &Parser = getParser();
4444 // Line should look like: ".set noat".
4446 // Set the $at register to $0.
4447 AssemblerOptions.back()->setATRegIndex(0);
4449 Parser.Lex(); // Eat "noat".
4451 // If this is not the end of the statement, report an error.
4452 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4453 reportParseError("unexpected token, expected end of statement");
4457 getTargetStreamer().emitDirectiveSetNoAt();
4458 Parser.Lex(); // Consume the EndOfStatement.
4462 bool MipsAsmParser::parseSetAtDirective() {
4463 // Line can be: ".set at", which sets $at to $1
4464 // or ".set at=$reg", which sets $at to $reg.
4465 MCAsmParser &Parser = getParser();
4466 Parser.Lex(); // Eat "at".
4468 if (getLexer().is(AsmToken::EndOfStatement)) {
4469 // No register was specified, so we set $at to $1.
4470 AssemblerOptions.back()->setATRegIndex(1);
4472 getTargetStreamer().emitDirectiveSetAt();
4473 Parser.Lex(); // Consume the EndOfStatement.
4477 if (getLexer().isNot(AsmToken::Equal)) {
4478 reportParseError("unexpected token, expected equals sign");
4481 Parser.Lex(); // Eat "=".
4483 if (getLexer().isNot(AsmToken::Dollar)) {
4484 if (getLexer().is(AsmToken::EndOfStatement)) {
4485 reportParseError("no register specified");
4488 reportParseError("unexpected token, expected dollar sign '$'");
4492 Parser.Lex(); // Eat "$".
4494 // Find out what "reg" is.
4496 const AsmToken &Reg = Parser.getTok();
4497 if (Reg.is(AsmToken::Identifier)) {
4498 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4499 } else if (Reg.is(AsmToken::Integer)) {
4500 AtRegNo = Reg.getIntVal();
4502 reportParseError("unexpected token, expected identifier or integer");
4506 // Check if $reg is a valid register. If it is, set $at to $reg.
4507 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4508 reportParseError("invalid register");
4511 Parser.Lex(); // Eat "reg".
4513 // If this is not the end of the statement, report an error.
4514 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4515 reportParseError("unexpected token, expected end of statement");
4519 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4521 Parser.Lex(); // Consume the EndOfStatement.
4525 bool MipsAsmParser::parseSetReorderDirective() {
4526 MCAsmParser &Parser = getParser();
4528 // If this is not the end of the statement, report an error.
4529 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4530 reportParseError("unexpected token, expected end of statement");
4533 AssemblerOptions.back()->setReorder();
4534 getTargetStreamer().emitDirectiveSetReorder();
4535 Parser.Lex(); // Consume the EndOfStatement.
4539 bool MipsAsmParser::parseSetNoReorderDirective() {
4540 MCAsmParser &Parser = getParser();
4542 // If this is not the end of the statement, report an error.
4543 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4544 reportParseError("unexpected token, expected end of statement");
4547 AssemblerOptions.back()->setNoReorder();
4548 getTargetStreamer().emitDirectiveSetNoReorder();
4549 Parser.Lex(); // Consume the EndOfStatement.
4553 bool MipsAsmParser::parseSetMacroDirective() {
4554 MCAsmParser &Parser = getParser();
4556 // If this is not the end of the statement, report an error.
4557 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4558 reportParseError("unexpected token, expected end of statement");
4561 AssemblerOptions.back()->setMacro();
4562 getTargetStreamer().emitDirectiveSetMacro();
4563 Parser.Lex(); // Consume the EndOfStatement.
4567 bool MipsAsmParser::parseSetNoMacroDirective() {
4568 MCAsmParser &Parser = getParser();
4570 // If this is not the end of the statement, report an error.
4571 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4572 reportParseError("unexpected token, expected end of statement");
4575 if (AssemblerOptions.back()->isReorder()) {
4576 reportParseError("`noreorder' must be set before `nomacro'");
4579 AssemblerOptions.back()->setNoMacro();
4580 getTargetStreamer().emitDirectiveSetNoMacro();
4581 Parser.Lex(); // Consume the EndOfStatement.
4585 bool MipsAsmParser::parseSetMsaDirective() {
4586 MCAsmParser &Parser = getParser();
4589 // If this is not the end of the statement, report an error.
4590 if (getLexer().isNot(AsmToken::EndOfStatement))
4591 return reportParseError("unexpected token, expected end of statement");
4593 setFeatureBits(Mips::FeatureMSA, "msa");
4594 getTargetStreamer().emitDirectiveSetMsa();
4598 bool MipsAsmParser::parseSetNoMsaDirective() {
4599 MCAsmParser &Parser = getParser();
4602 // If this is not the end of the statement, report an error.
4603 if (getLexer().isNot(AsmToken::EndOfStatement))
4604 return reportParseError("unexpected token, expected end of statement");
4606 clearFeatureBits(Mips::FeatureMSA, "msa");
4607 getTargetStreamer().emitDirectiveSetNoMsa();
4611 bool MipsAsmParser::parseSetNoDspDirective() {
4612 MCAsmParser &Parser = getParser();
4613 Parser.Lex(); // Eat "nodsp".
4615 // If this is not the end of the statement, report an error.
4616 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4617 reportParseError("unexpected token, expected end of statement");
4621 clearFeatureBits(Mips::FeatureDSP, "dsp");
4622 getTargetStreamer().emitDirectiveSetNoDsp();
4626 bool MipsAsmParser::parseSetMips16Directive() {
4627 MCAsmParser &Parser = getParser();
4628 Parser.Lex(); // Eat "mips16".
4630 // If this is not the end of the statement, report an error.
4631 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4632 reportParseError("unexpected token, expected end of statement");
4636 setFeatureBits(Mips::FeatureMips16, "mips16");
4637 getTargetStreamer().emitDirectiveSetMips16();
4638 Parser.Lex(); // Consume the EndOfStatement.
4642 bool MipsAsmParser::parseSetNoMips16Directive() {
4643 MCAsmParser &Parser = getParser();
4644 Parser.Lex(); // Eat "nomips16".
4646 // If this is not the end of the statement, report an error.
4647 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4648 reportParseError("unexpected token, expected end of statement");
4652 clearFeatureBits(Mips::FeatureMips16, "mips16");
4653 getTargetStreamer().emitDirectiveSetNoMips16();
4654 Parser.Lex(); // Consume the EndOfStatement.
4658 bool MipsAsmParser::parseSetFpDirective() {
4659 MCAsmParser &Parser = getParser();
4660 MipsABIFlagsSection::FpABIKind FpAbiVal;
4661 // Line can be: .set fp=32
4664 Parser.Lex(); // Eat fp token
4665 AsmToken Tok = Parser.getTok();
4666 if (Tok.isNot(AsmToken::Equal)) {
4667 reportParseError("unexpected token, expected equals sign '='");
4670 Parser.Lex(); // Eat '=' token.
4671 Tok = Parser.getTok();
4673 if (!parseFpABIValue(FpAbiVal, ".set"))
4676 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4677 reportParseError("unexpected token, expected end of statement");
4680 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4681 Parser.Lex(); // Consume the EndOfStatement.
4685 bool MipsAsmParser::parseSetOddSPRegDirective() {
4686 MCAsmParser &Parser = getParser();
4688 Parser.Lex(); // Eat "oddspreg".
4689 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4690 reportParseError("unexpected token, expected end of statement");
4694 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4695 getTargetStreamer().emitDirectiveSetOddSPReg();
4699 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4700 MCAsmParser &Parser = getParser();
4702 Parser.Lex(); // Eat "nooddspreg".
4703 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4704 reportParseError("unexpected token, expected end of statement");
4708 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4709 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4713 bool MipsAsmParser::parseSetPopDirective() {
4714 MCAsmParser &Parser = getParser();
4715 SMLoc Loc = getLexer().getLoc();
4718 if (getLexer().isNot(AsmToken::EndOfStatement))
4719 return reportParseError("unexpected token, expected end of statement");
4721 // Always keep an element on the options "stack" to prevent the user
4722 // from changing the initial options. This is how we remember them.
4723 if (AssemblerOptions.size() == 2)
4724 return reportParseError(Loc, ".set pop with no .set push");
4726 AssemblerOptions.pop_back();
4727 setAvailableFeatures(
4728 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4729 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4731 getTargetStreamer().emitDirectiveSetPop();
4735 bool MipsAsmParser::parseSetPushDirective() {
4736 MCAsmParser &Parser = getParser();
4738 if (getLexer().isNot(AsmToken::EndOfStatement))
4739 return reportParseError("unexpected token, expected end of statement");
4741 // Create a copy of the current assembler options environment and push it.
4742 AssemblerOptions.push_back(
4743 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4745 getTargetStreamer().emitDirectiveSetPush();
4749 bool MipsAsmParser::parseSetSoftFloatDirective() {
4750 MCAsmParser &Parser = getParser();
4752 if (getLexer().isNot(AsmToken::EndOfStatement))
4753 return reportParseError("unexpected token, expected end of statement");
4755 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4756 getTargetStreamer().emitDirectiveSetSoftFloat();
4760 bool MipsAsmParser::parseSetHardFloatDirective() {
4761 MCAsmParser &Parser = getParser();
4763 if (getLexer().isNot(AsmToken::EndOfStatement))
4764 return reportParseError("unexpected token, expected end of statement");
4766 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4767 getTargetStreamer().emitDirectiveSetHardFloat();
4771 bool MipsAsmParser::parseSetAssignment() {
4773 const MCExpr *Value;
4774 MCAsmParser &Parser = getParser();
4776 if (Parser.parseIdentifier(Name))
4777 reportParseError("expected identifier after .set");
4779 if (getLexer().isNot(AsmToken::Comma))
4780 return reportParseError("unexpected token, expected comma");
4783 if (Parser.parseExpression(Value))
4784 return reportParseError("expected valid expression after comma");
4786 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4787 Sym->setVariableValue(Value);
4792 bool MipsAsmParser::parseSetMips0Directive() {
4793 MCAsmParser &Parser = getParser();
4795 if (getLexer().isNot(AsmToken::EndOfStatement))
4796 return reportParseError("unexpected token, expected end of statement");
4798 // Reset assembler options to their initial values.
4799 setAvailableFeatures(
4800 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4801 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4802 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4804 getTargetStreamer().emitDirectiveSetMips0();
4808 bool MipsAsmParser::parseSetArchDirective() {
4809 MCAsmParser &Parser = getParser();
4811 if (getLexer().isNot(AsmToken::Equal))
4812 return reportParseError("unexpected token, expected equals sign");
4816 if (Parser.parseIdentifier(Arch))
4817 return reportParseError("expected arch identifier");
4819 StringRef ArchFeatureName =
4820 StringSwitch<StringRef>(Arch)
4821 .Case("mips1", "mips1")
4822 .Case("mips2", "mips2")
4823 .Case("mips3", "mips3")
4824 .Case("mips4", "mips4")
4825 .Case("mips5", "mips5")
4826 .Case("mips32", "mips32")
4827 .Case("mips32r2", "mips32r2")
4828 .Case("mips32r3", "mips32r3")
4829 .Case("mips32r5", "mips32r5")
4830 .Case("mips32r6", "mips32r6")
4831 .Case("mips64", "mips64")
4832 .Case("mips64r2", "mips64r2")
4833 .Case("mips64r3", "mips64r3")
4834 .Case("mips64r5", "mips64r5")
4835 .Case("mips64r6", "mips64r6")
4836 .Case("cnmips", "cnmips")
4837 .Case("r4000", "mips3") // This is an implementation of Mips3.
4840 if (ArchFeatureName.empty())
4841 return reportParseError("unsupported architecture");
4843 selectArch(ArchFeatureName);
4844 getTargetStreamer().emitDirectiveSetArch(Arch);
4848 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4849 MCAsmParser &Parser = getParser();
4851 if (getLexer().isNot(AsmToken::EndOfStatement))
4852 return reportParseError("unexpected token, expected end of statement");
4856 llvm_unreachable("Unimplemented feature");
4857 case Mips::FeatureDSP:
4858 setFeatureBits(Mips::FeatureDSP, "dsp");
4859 getTargetStreamer().emitDirectiveSetDsp();
4861 case Mips::FeatureMicroMips:
4862 getTargetStreamer().emitDirectiveSetMicroMips();
4864 case Mips::FeatureMips1:
4865 selectArch("mips1");
4866 getTargetStreamer().emitDirectiveSetMips1();
4868 case Mips::FeatureMips2:
4869 selectArch("mips2");
4870 getTargetStreamer().emitDirectiveSetMips2();
4872 case Mips::FeatureMips3:
4873 selectArch("mips3");
4874 getTargetStreamer().emitDirectiveSetMips3();
4876 case Mips::FeatureMips4:
4877 selectArch("mips4");
4878 getTargetStreamer().emitDirectiveSetMips4();
4880 case Mips::FeatureMips5:
4881 selectArch("mips5");
4882 getTargetStreamer().emitDirectiveSetMips5();
4884 case Mips::FeatureMips32:
4885 selectArch("mips32");
4886 getTargetStreamer().emitDirectiveSetMips32();
4888 case Mips::FeatureMips32r2:
4889 selectArch("mips32r2");
4890 getTargetStreamer().emitDirectiveSetMips32R2();
4892 case Mips::FeatureMips32r3:
4893 selectArch("mips32r3");
4894 getTargetStreamer().emitDirectiveSetMips32R3();
4896 case Mips::FeatureMips32r5:
4897 selectArch("mips32r5");
4898 getTargetStreamer().emitDirectiveSetMips32R5();
4900 case Mips::FeatureMips32r6:
4901 selectArch("mips32r6");
4902 getTargetStreamer().emitDirectiveSetMips32R6();
4904 case Mips::FeatureMips64:
4905 selectArch("mips64");
4906 getTargetStreamer().emitDirectiveSetMips64();
4908 case Mips::FeatureMips64r2:
4909 selectArch("mips64r2");
4910 getTargetStreamer().emitDirectiveSetMips64R2();
4912 case Mips::FeatureMips64r3:
4913 selectArch("mips64r3");
4914 getTargetStreamer().emitDirectiveSetMips64R3();
4916 case Mips::FeatureMips64r5:
4917 selectArch("mips64r5");
4918 getTargetStreamer().emitDirectiveSetMips64R5();
4920 case Mips::FeatureMips64r6:
4921 selectArch("mips64r6");
4922 getTargetStreamer().emitDirectiveSetMips64R6();
4928 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4929 MCAsmParser &Parser = getParser();
4930 if (getLexer().isNot(AsmToken::Comma)) {
4931 SMLoc Loc = getLexer().getLoc();
4932 Parser.eatToEndOfStatement();
4933 return Error(Loc, ErrorStr);
4936 Parser.Lex(); // Eat the comma.
4940 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4941 // In this class, it is only used for .cprestore.
4942 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4943 // MipsTargetELFStreamer and MipsAsmParser.
4944 bool MipsAsmParser::isPicAndNotNxxAbi() {
4945 return inPicMode() && !(isABI_N32() || isABI_N64());
4948 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4949 if (AssemblerOptions.back()->isReorder())
4950 Warning(Loc, ".cpload should be inside a noreorder section");
4952 if (inMips16Mode()) {
4953 reportParseError(".cpload is not supported in Mips16 mode");
4957 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4958 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4959 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4960 reportParseError("expected register containing function address");
4964 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4965 if (!RegOpnd.isGPRAsmReg()) {
4966 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4970 // If this is not the end of the statement, report an error.
4971 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4972 reportParseError("unexpected token, expected end of statement");
4976 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4980 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4981 MCAsmParser &Parser = getParser();
4983 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4984 // is used in non-PIC mode.
4986 if (inMips16Mode()) {
4987 reportParseError(".cprestore is not supported in Mips16 mode");
4991 // Get the stack offset value.
4992 const MCExpr *StackOffset;
4993 int64_t StackOffsetVal;
4994 if (Parser.parseExpression(StackOffset)) {
4995 reportParseError("expected stack offset value");
4999 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5000 reportParseError("stack offset is not an absolute expression");
5004 if (StackOffsetVal < 0) {
5005 Warning(Loc, ".cprestore with negative stack offset has no effect");
5006 IsCpRestoreSet = false;
5008 IsCpRestoreSet = true;
5009 CpRestoreOffset = StackOffsetVal;
5012 // If this is not the end of the statement, report an error.
5013 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5014 reportParseError("unexpected token, expected end of statement");
5018 // Store the $gp on the stack.
5019 SmallVector<MCInst, 3> StoreInsts;
5020 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5023 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
5024 Parser.Lex(); // Consume the EndOfStatement.
5028 bool MipsAsmParser::parseDirectiveCPSetup() {
5029 MCAsmParser &Parser = getParser();
5032 bool SaveIsReg = true;
5034 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5035 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5036 if (ResTy == MatchOperand_NoMatch) {
5037 reportParseError("expected register containing function address");
5038 Parser.eatToEndOfStatement();
5042 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5043 if (!FuncRegOpnd.isGPRAsmReg()) {
5044 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5045 Parser.eatToEndOfStatement();
5049 FuncReg = FuncRegOpnd.getGPR32Reg();
5052 if (!eatComma("unexpected token, expected comma"))
5055 ResTy = parseAnyRegister(TmpReg);
5056 if (ResTy == MatchOperand_NoMatch) {
5057 const MCExpr *OffsetExpr;
5059 SMLoc ExprLoc = getLexer().getLoc();
5061 if (Parser.parseExpression(OffsetExpr) ||
5062 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5063 reportParseError(ExprLoc, "expected save register or stack offset");
5064 Parser.eatToEndOfStatement();
5071 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5072 if (!SaveOpnd.isGPRAsmReg()) {
5073 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5074 Parser.eatToEndOfStatement();
5077 Save = SaveOpnd.getGPR32Reg();
5080 if (!eatComma("unexpected token, expected comma"))
5084 if (Parser.parseExpression(Expr)) {
5085 reportParseError("expected expression");
5089 if (Expr->getKind() != MCExpr::SymbolRef) {
5090 reportParseError("expected symbol");
5093 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5095 CpSaveLocation = Save;
5096 CpSaveLocationIsRegister = SaveIsReg;
5098 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5103 bool MipsAsmParser::parseDirectiveCPReturn() {
5104 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5105 CpSaveLocationIsRegister);
5109 bool MipsAsmParser::parseDirectiveNaN() {
5110 MCAsmParser &Parser = getParser();
5111 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5112 const AsmToken &Tok = Parser.getTok();
5114 if (Tok.getString() == "2008") {
5116 getTargetStreamer().emitDirectiveNaN2008();
5118 } else if (Tok.getString() == "legacy") {
5120 getTargetStreamer().emitDirectiveNaNLegacy();
5124 // If we don't recognize the option passed to the .nan
5125 // directive (e.g. no option or unknown option), emit an error.
5126 reportParseError("invalid option in .nan directive");
5130 bool MipsAsmParser::parseDirectiveSet() {
5131 MCAsmParser &Parser = getParser();
5132 // Get the next token.
5133 const AsmToken &Tok = Parser.getTok();
5135 if (Tok.getString() == "noat") {
5136 return parseSetNoAtDirective();
5137 } else if (Tok.getString() == "at") {
5138 return parseSetAtDirective();
5139 } else if (Tok.getString() == "arch") {
5140 return parseSetArchDirective();
5141 } else if (Tok.getString() == "fp") {
5142 return parseSetFpDirective();
5143 } else if (Tok.getString() == "oddspreg") {
5144 return parseSetOddSPRegDirective();
5145 } else if (Tok.getString() == "nooddspreg") {
5146 return parseSetNoOddSPRegDirective();
5147 } else if (Tok.getString() == "pop") {
5148 return parseSetPopDirective();
5149 } else if (Tok.getString() == "push") {
5150 return parseSetPushDirective();
5151 } else if (Tok.getString() == "reorder") {
5152 return parseSetReorderDirective();
5153 } else if (Tok.getString() == "noreorder") {
5154 return parseSetNoReorderDirective();
5155 } else if (Tok.getString() == "macro") {
5156 return parseSetMacroDirective();
5157 } else if (Tok.getString() == "nomacro") {
5158 return parseSetNoMacroDirective();
5159 } else if (Tok.getString() == "mips16") {
5160 return parseSetMips16Directive();
5161 } else if (Tok.getString() == "nomips16") {
5162 return parseSetNoMips16Directive();
5163 } else if (Tok.getString() == "nomicromips") {
5164 getTargetStreamer().emitDirectiveSetNoMicroMips();
5165 Parser.eatToEndOfStatement();
5167 } else if (Tok.getString() == "micromips") {
5168 return parseSetFeature(Mips::FeatureMicroMips);
5169 } else if (Tok.getString() == "mips0") {
5170 return parseSetMips0Directive();
5171 } else if (Tok.getString() == "mips1") {
5172 return parseSetFeature(Mips::FeatureMips1);
5173 } else if (Tok.getString() == "mips2") {
5174 return parseSetFeature(Mips::FeatureMips2);
5175 } else if (Tok.getString() == "mips3") {
5176 return parseSetFeature(Mips::FeatureMips3);
5177 } else if (Tok.getString() == "mips4") {
5178 return parseSetFeature(Mips::FeatureMips4);
5179 } else if (Tok.getString() == "mips5") {
5180 return parseSetFeature(Mips::FeatureMips5);
5181 } else if (Tok.getString() == "mips32") {
5182 return parseSetFeature(Mips::FeatureMips32);
5183 } else if (Tok.getString() == "mips32r2") {
5184 return parseSetFeature(Mips::FeatureMips32r2);
5185 } else if (Tok.getString() == "mips32r3") {
5186 return parseSetFeature(Mips::FeatureMips32r3);
5187 } else if (Tok.getString() == "mips32r5") {
5188 return parseSetFeature(Mips::FeatureMips32r5);
5189 } else if (Tok.getString() == "mips32r6") {
5190 return parseSetFeature(Mips::FeatureMips32r6);
5191 } else if (Tok.getString() == "mips64") {
5192 return parseSetFeature(Mips::FeatureMips64);
5193 } else if (Tok.getString() == "mips64r2") {
5194 return parseSetFeature(Mips::FeatureMips64r2);
5195 } else if (Tok.getString() == "mips64r3") {
5196 return parseSetFeature(Mips::FeatureMips64r3);
5197 } else if (Tok.getString() == "mips64r5") {
5198 return parseSetFeature(Mips::FeatureMips64r5);
5199 } else if (Tok.getString() == "mips64r6") {
5200 return parseSetFeature(Mips::FeatureMips64r6);
5201 } else if (Tok.getString() == "dsp") {
5202 return parseSetFeature(Mips::FeatureDSP);
5203 } else if (Tok.getString() == "nodsp") {
5204 return parseSetNoDspDirective();
5205 } else if (Tok.getString() == "msa") {
5206 return parseSetMsaDirective();
5207 } else if (Tok.getString() == "nomsa") {
5208 return parseSetNoMsaDirective();
5209 } else if (Tok.getString() == "softfloat") {
5210 return parseSetSoftFloatDirective();
5211 } else if (Tok.getString() == "hardfloat") {
5212 return parseSetHardFloatDirective();
5214 // It is just an identifier, look for an assignment.
5215 parseSetAssignment();
5222 /// parseDataDirective
5223 /// ::= .word [ expression (, expression)* ]
5224 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5225 MCAsmParser &Parser = getParser();
5226 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5228 const MCExpr *Value;
5229 if (getParser().parseExpression(Value))
5232 getParser().getStreamer().EmitValue(Value, Size);
5234 if (getLexer().is(AsmToken::EndOfStatement))
5237 if (getLexer().isNot(AsmToken::Comma))
5238 return Error(L, "unexpected token, expected comma");
5247 /// parseDirectiveGpWord
5248 /// ::= .gpword local_sym
5249 bool MipsAsmParser::parseDirectiveGpWord() {
5250 MCAsmParser &Parser = getParser();
5251 const MCExpr *Value;
5252 // EmitGPRel32Value requires an expression, so we are using base class
5253 // method to evaluate the expression.
5254 if (getParser().parseExpression(Value))
5256 getParser().getStreamer().EmitGPRel32Value(Value);
5258 if (getLexer().isNot(AsmToken::EndOfStatement))
5259 return Error(getLexer().getLoc(),
5260 "unexpected token, expected end of statement");
5261 Parser.Lex(); // Eat EndOfStatement token.
5265 /// parseDirectiveGpDWord
5266 /// ::= .gpdword local_sym
5267 bool MipsAsmParser::parseDirectiveGpDWord() {
5268 MCAsmParser &Parser = getParser();
5269 const MCExpr *Value;
5270 // EmitGPRel64Value requires an expression, so we are using base class
5271 // method to evaluate the expression.
5272 if (getParser().parseExpression(Value))
5274 getParser().getStreamer().EmitGPRel64Value(Value);
5276 if (getLexer().isNot(AsmToken::EndOfStatement))
5277 return Error(getLexer().getLoc(),
5278 "unexpected token, expected end of statement");
5279 Parser.Lex(); // Eat EndOfStatement token.
5283 bool MipsAsmParser::parseDirectiveOption() {
5284 MCAsmParser &Parser = getParser();
5285 // Get the option token.
5286 AsmToken Tok = Parser.getTok();
5287 // At the moment only identifiers are supported.
5288 if (Tok.isNot(AsmToken::Identifier)) {
5289 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5290 Parser.eatToEndOfStatement();
5294 StringRef Option = Tok.getIdentifier();
5296 if (Option == "pic0") {
5297 // MipsAsmParser needs to know if the current PIC mode changes.
5298 IsPicEnabled = false;
5300 getTargetStreamer().emitDirectiveOptionPic0();
5302 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5303 Error(Parser.getTok().getLoc(),
5304 "unexpected token, expected end of statement");
5305 Parser.eatToEndOfStatement();
5310 if (Option == "pic2") {
5311 // MipsAsmParser needs to know if the current PIC mode changes.
5312 IsPicEnabled = true;
5314 getTargetStreamer().emitDirectiveOptionPic2();
5316 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5317 Error(Parser.getTok().getLoc(),
5318 "unexpected token, expected end of statement");
5319 Parser.eatToEndOfStatement();
5325 Warning(Parser.getTok().getLoc(),
5326 "unknown option, expected 'pic0' or 'pic2'");
5327 Parser.eatToEndOfStatement();
5331 /// parseInsnDirective
5333 bool MipsAsmParser::parseInsnDirective() {
5334 // If this is not the end of the statement, report an error.
5335 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5336 reportParseError("unexpected token, expected end of statement");
5340 // The actual label marking happens in
5341 // MipsELFStreamer::createPendingLabelRelocs().
5342 getTargetStreamer().emitDirectiveInsn();
5344 getParser().Lex(); // Eat EndOfStatement token.
5348 /// parseDirectiveModule
5349 /// ::= .module oddspreg
5350 /// ::= .module nooddspreg
5351 /// ::= .module fp=value
5352 /// ::= .module softfloat
5353 /// ::= .module hardfloat
5354 bool MipsAsmParser::parseDirectiveModule() {
5355 MCAsmParser &Parser = getParser();
5356 MCAsmLexer &Lexer = getLexer();
5357 SMLoc L = Lexer.getLoc();
5359 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5360 // TODO : get a better message.
5361 reportParseError(".module directive must appear before any code");
5366 if (Parser.parseIdentifier(Option)) {
5367 reportParseError("expected .module option identifier");
5371 if (Option == "oddspreg") {
5372 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5374 // Synchronize the abiflags information with the FeatureBits information we
5376 getTargetStreamer().updateABIInfo(*this);
5378 // If printing assembly, use the recently updated abiflags information.
5379 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5380 // emitted at the end).
5381 getTargetStreamer().emitDirectiveModuleOddSPReg();
5383 // If this is not the end of the statement, report an error.
5384 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5385 reportParseError("unexpected token, expected end of statement");
5389 return false; // parseDirectiveModule has finished successfully.
5390 } else if (Option == "nooddspreg") {
5392 Error(L, "'.module nooddspreg' requires the O32 ABI");
5396 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5398 // Synchronize the abiflags information with the FeatureBits information we
5400 getTargetStreamer().updateABIInfo(*this);
5402 // If printing assembly, use the recently updated abiflags information.
5403 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5404 // emitted at the end).
5405 getTargetStreamer().emitDirectiveModuleOddSPReg();
5407 // If this is not the end of the statement, report an error.
5408 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5409 reportParseError("unexpected token, expected end of statement");
5413 return false; // parseDirectiveModule has finished successfully.
5414 } else if (Option == "fp") {
5415 return parseDirectiveModuleFP();
5416 } else if (Option == "softfloat") {
5417 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5419 // Synchronize the ABI Flags information with the FeatureBits information we
5421 getTargetStreamer().updateABIInfo(*this);
5423 // If printing assembly, use the recently updated ABI Flags information.
5424 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5426 getTargetStreamer().emitDirectiveModuleSoftFloat();
5428 // If this is not the end of the statement, report an error.
5429 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5430 reportParseError("unexpected token, expected end of statement");
5434 return false; // parseDirectiveModule has finished successfully.
5435 } else if (Option == "hardfloat") {
5436 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5438 // Synchronize the ABI Flags information with the FeatureBits information we
5440 getTargetStreamer().updateABIInfo(*this);
5442 // If printing assembly, use the recently updated ABI Flags information.
5443 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5445 getTargetStreamer().emitDirectiveModuleHardFloat();
5447 // If this is not the end of the statement, report an error.
5448 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5449 reportParseError("unexpected token, expected end of statement");
5453 return false; // parseDirectiveModule has finished successfully.
5455 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5459 /// parseDirectiveModuleFP
5463 bool MipsAsmParser::parseDirectiveModuleFP() {
5464 MCAsmParser &Parser = getParser();
5465 MCAsmLexer &Lexer = getLexer();
5467 if (Lexer.isNot(AsmToken::Equal)) {
5468 reportParseError("unexpected token, expected equals sign '='");
5471 Parser.Lex(); // Eat '=' token.
5473 MipsABIFlagsSection::FpABIKind FpABI;
5474 if (!parseFpABIValue(FpABI, ".module"))
5477 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5478 reportParseError("unexpected token, expected end of statement");
5482 // Synchronize the abiflags information with the FeatureBits information we
5484 getTargetStreamer().updateABIInfo(*this);
5486 // If printing assembly, use the recently updated abiflags information.
5487 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5488 // emitted at the end).
5489 getTargetStreamer().emitDirectiveModuleFP();
5491 Parser.Lex(); // Consume the EndOfStatement.
5495 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5496 StringRef Directive) {
5497 MCAsmParser &Parser = getParser();
5498 MCAsmLexer &Lexer = getLexer();
5499 bool ModuleLevelOptions = Directive == ".module";
5501 if (Lexer.is(AsmToken::Identifier)) {
5502 StringRef Value = Parser.getTok().getString();
5505 if (Value != "xx") {
5506 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5511 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5515 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5516 if (ModuleLevelOptions) {
5517 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5518 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5520 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5521 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5526 if (Lexer.is(AsmToken::Integer)) {
5527 unsigned Value = Parser.getTok().getIntVal();
5530 if (Value != 32 && Value != 64) {
5531 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5537 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5541 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5542 if (ModuleLevelOptions) {
5543 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5544 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5546 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5547 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5550 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5551 if (ModuleLevelOptions) {
5552 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5553 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5555 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5556 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5566 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5567 MCAsmParser &Parser = getParser();
5568 StringRef IDVal = DirectiveID.getString();
5570 if (IDVal == ".cpload")
5571 return parseDirectiveCpLoad(DirectiveID.getLoc());
5572 if (IDVal == ".cprestore")
5573 return parseDirectiveCpRestore(DirectiveID.getLoc());
5574 if (IDVal == ".dword") {
5575 parseDataDirective(8, DirectiveID.getLoc());
5578 if (IDVal == ".ent") {
5579 StringRef SymbolName;
5581 if (Parser.parseIdentifier(SymbolName)) {
5582 reportParseError("expected identifier after .ent");
5586 // There's an undocumented extension that allows an integer to
5587 // follow the name of the procedure which AFAICS is ignored by GAS.
5588 // Example: .ent foo,2
5589 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5590 if (getLexer().isNot(AsmToken::Comma)) {
5591 // Even though we accept this undocumented extension for compatibility
5592 // reasons, the additional integer argument does not actually change
5593 // the behaviour of the '.ent' directive, so we would like to discourage
5594 // its use. We do this by not referring to the extended version in
5595 // error messages which are not directly related to its use.
5596 reportParseError("unexpected token, expected end of statement");
5599 Parser.Lex(); // Eat the comma.
5600 const MCExpr *DummyNumber;
5601 int64_t DummyNumberVal;
5602 // If the user was explicitly trying to use the extended version,
5603 // we still give helpful extension-related error messages.
5604 if (Parser.parseExpression(DummyNumber)) {
5605 reportParseError("expected number after comma");
5608 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5609 reportParseError("expected an absolute expression after comma");
5614 // If this is not the end of the statement, report an error.
5615 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5616 reportParseError("unexpected token, expected end of statement");
5620 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5622 getTargetStreamer().emitDirectiveEnt(*Sym);
5624 IsCpRestoreSet = false;
5628 if (IDVal == ".end") {
5629 StringRef SymbolName;
5631 if (Parser.parseIdentifier(SymbolName)) {
5632 reportParseError("expected identifier after .end");
5636 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5637 reportParseError("unexpected token, expected end of statement");
5641 if (CurrentFn == nullptr) {
5642 reportParseError(".end used without .ent");
5646 if ((SymbolName != CurrentFn->getName())) {
5647 reportParseError(".end symbol does not match .ent symbol");
5651 getTargetStreamer().emitDirectiveEnd(SymbolName);
5652 CurrentFn = nullptr;
5653 IsCpRestoreSet = false;
5657 if (IDVal == ".frame") {
5658 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5659 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5660 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5661 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5662 reportParseError("expected stack register");
5666 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5667 if (!StackRegOpnd.isGPRAsmReg()) {
5668 reportParseError(StackRegOpnd.getStartLoc(),
5669 "expected general purpose register");
5672 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5674 if (Parser.getTok().is(AsmToken::Comma))
5677 reportParseError("unexpected token, expected comma");
5681 // Parse the frame size.
5682 const MCExpr *FrameSize;
5683 int64_t FrameSizeVal;
5685 if (Parser.parseExpression(FrameSize)) {
5686 reportParseError("expected frame size value");
5690 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5691 reportParseError("frame size not an absolute expression");
5695 if (Parser.getTok().is(AsmToken::Comma))
5698 reportParseError("unexpected token, expected comma");
5702 // Parse the return register.
5704 ResTy = parseAnyRegister(TmpReg);
5705 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5706 reportParseError("expected return register");
5710 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5711 if (!ReturnRegOpnd.isGPRAsmReg()) {
5712 reportParseError(ReturnRegOpnd.getStartLoc(),
5713 "expected general purpose register");
5717 // If this is not the end of the statement, report an error.
5718 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5719 reportParseError("unexpected token, expected end of statement");
5723 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5724 ReturnRegOpnd.getGPR32Reg());
5725 IsCpRestoreSet = false;
5729 if (IDVal == ".set") {
5730 return parseDirectiveSet();
5733 if (IDVal == ".mask" || IDVal == ".fmask") {
5734 // .mask bitmask, frame_offset
5735 // bitmask: One bit for each register used.
5736 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5737 // first register is expected to be saved.
5739 // .mask 0x80000000, -4
5740 // .fmask 0x80000000, -4
5743 // Parse the bitmask
5744 const MCExpr *BitMask;
5747 if (Parser.parseExpression(BitMask)) {
5748 reportParseError("expected bitmask value");
5752 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5753 reportParseError("bitmask not an absolute expression");
5757 if (Parser.getTok().is(AsmToken::Comma))
5760 reportParseError("unexpected token, expected comma");
5764 // Parse the frame_offset
5765 const MCExpr *FrameOffset;
5766 int64_t FrameOffsetVal;
5768 if (Parser.parseExpression(FrameOffset)) {
5769 reportParseError("expected frame offset value");
5773 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5774 reportParseError("frame offset not an absolute expression");
5778 // If this is not the end of the statement, report an error.
5779 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5780 reportParseError("unexpected token, expected end of statement");
5784 if (IDVal == ".mask")
5785 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5787 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5791 if (IDVal == ".nan")
5792 return parseDirectiveNaN();
5794 if (IDVal == ".gpword") {
5795 parseDirectiveGpWord();
5799 if (IDVal == ".gpdword") {
5800 parseDirectiveGpDWord();
5804 if (IDVal == ".word") {
5805 parseDataDirective(4, DirectiveID.getLoc());
5809 if (IDVal == ".option")
5810 return parseDirectiveOption();
5812 if (IDVal == ".abicalls") {
5813 getTargetStreamer().emitDirectiveAbiCalls();
5814 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5815 Error(Parser.getTok().getLoc(),
5816 "unexpected token, expected end of statement");
5818 Parser.eatToEndOfStatement();
5823 if (IDVal == ".cpsetup")
5824 return parseDirectiveCPSetup();
5826 if (IDVal == ".cpreturn")
5827 return parseDirectiveCPReturn();
5829 if (IDVal == ".module")
5830 return parseDirectiveModule();
5832 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5833 return parseInternalDirectiveReallowModule();
5835 if (IDVal == ".insn")
5836 return parseInsnDirective();
5841 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5842 // If this is not the end of the statement, report an error.
5843 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5844 reportParseError("unexpected token, expected end of statement");
5848 getTargetStreamer().reallowModuleDirective();
5850 getParser().Lex(); // Eat EndOfStatement token.
5854 extern "C" void LLVMInitializeMipsAsmParser() {
5855 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5856 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5857 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5858 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5861 #define GET_REGISTER_MATCHER
5862 #define GET_MATCHER_IMPLEMENTATION
5863 #include "MipsGenAsmMatcher.inc"