1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCParser/MCAsmLexer.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCTargetAsmParser.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
38 #define DEBUG_TYPE "mips-asm-parser"
45 class MipsAssemblerOptions {
47 MipsAssemblerOptions(const FeatureBitset &Features_) :
48 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
50 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
51 ATReg = Opts->getATRegIndex();
52 Reorder = Opts->isReorder();
53 Macro = Opts->isMacro();
54 Features = Opts->getFeatures();
57 unsigned getATRegIndex() const { return ATReg; }
58 bool setATRegIndex(unsigned Reg) {
66 bool isReorder() const { return Reorder; }
67 void setReorder() { Reorder = true; }
68 void setNoReorder() { Reorder = false; }
70 bool isMacro() const { return Macro; }
71 void setMacro() { Macro = true; }
72 void setNoMacro() { Macro = false; }
74 const FeatureBitset &getFeatures() const { return Features; }
75 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
77 // Set of features that are either architecture features or referenced
78 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
79 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
80 // The reason we need this mask is explained in the selectArch function.
81 // FIXME: Ideally we would like TableGen to generate this information.
82 static const FeatureBitset AllArchRelatedMask;
88 FeatureBitset Features;
92 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
93 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
94 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
95 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
96 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
97 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
98 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
99 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
100 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
104 class MipsAsmParser : public MCTargetAsmParser {
105 MipsTargetStreamer &getTargetStreamer() {
106 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
107 return static_cast<MipsTargetStreamer &>(TS);
110 MCSubtargetInfo &STI;
112 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
113 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
114 // nullptr, which indicates that no function is currently
115 // selected. This usually happens after an '.end func'
121 unsigned CpSaveLocation;
122 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
123 bool CpSaveLocationIsRegister;
125 // Print a warning along with its fix-it message at the given range.
126 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
127 SMRange Range, bool ShowColors = true);
129 #define GET_ASSEMBLER_HEADER
130 #include "MipsGenAsmMatcher.inc"
132 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
134 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
135 OperandVector &Operands, MCStreamer &Out,
137 bool MatchingInlineAsm) override;
139 /// Parse a register as used in CFI directives
140 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
142 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
144 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
146 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
147 SMLoc NameLoc, OperandVector &Operands) override;
149 bool ParseDirective(AsmToken DirectiveID) override;
151 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
153 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
154 StringRef Identifier, SMLoc S);
155 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
157 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
158 OperandMatchResultTy parseImm(OperandVector &Operands);
159 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
160 OperandMatchResultTy parseInvNum(OperandVector &Operands);
161 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
163 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
164 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
166 bool searchSymbolAlias(OperandVector &Operands);
168 bool parseOperand(OperandVector &, StringRef Mnemonic);
170 enum MacroExpanderResultTy {
176 // Expands assembly pseudo instructions.
177 MacroExpanderResultTy
178 tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
179 SmallVectorImpl<MCInst> &Instructions);
181 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
182 SmallVectorImpl<MCInst> &Instructions);
184 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
185 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
189 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
195 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
196 const MCOperand &Offset, bool Is32BitAddress,
197 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
199 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
200 SmallVectorImpl<MCInst> &Instructions);
202 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
206 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
207 SmallVectorImpl<MCInst> &Instructions);
209 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
210 SmallVectorImpl<MCInst> &Instructions);
212 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
213 SmallVectorImpl<MCInst> &Instructions);
215 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
216 SmallVectorImpl<MCInst> &Instructions);
218 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
222 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
223 SmallVectorImpl<MCInst> &Instructions);
225 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
226 SmallVectorImpl<MCInst> &Instructions);
228 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
229 SmallVectorImpl<MCInst> &Instructions);
231 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
232 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
234 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
235 SmallVectorImpl<MCInst> &Instructions);
237 bool reportParseError(Twine ErrorMsg);
238 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
240 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
241 bool parseRelocOperand(const MCExpr *&Res);
243 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
245 bool isEvaluated(const MCExpr *Expr);
246 bool parseSetMips0Directive();
247 bool parseSetArchDirective();
248 bool parseSetFeature(uint64_t Feature);
249 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
250 bool parseDirectiveCpLoad(SMLoc Loc);
251 bool parseDirectiveCpRestore(SMLoc Loc);
252 bool parseDirectiveCPSetup();
253 bool parseDirectiveCPReturn();
254 bool parseDirectiveNaN();
255 bool parseDirectiveSet();
256 bool parseDirectiveOption();
257 bool parseInsnDirective();
259 bool parseSetAtDirective();
260 bool parseSetNoAtDirective();
261 bool parseSetMacroDirective();
262 bool parseSetNoMacroDirective();
263 bool parseSetMsaDirective();
264 bool parseSetNoMsaDirective();
265 bool parseSetNoDspDirective();
266 bool parseSetReorderDirective();
267 bool parseSetNoReorderDirective();
268 bool parseSetMips16Directive();
269 bool parseSetNoMips16Directive();
270 bool parseSetFpDirective();
271 bool parseSetOddSPRegDirective();
272 bool parseSetNoOddSPRegDirective();
273 bool parseSetPopDirective();
274 bool parseSetPushDirective();
275 bool parseSetSoftFloatDirective();
276 bool parseSetHardFloatDirective();
278 bool parseSetAssignment();
280 bool parseDataDirective(unsigned Size, SMLoc L);
281 bool parseDirectiveGpWord();
282 bool parseDirectiveGpDWord();
283 bool parseDirectiveModule();
284 bool parseDirectiveModuleFP();
285 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
286 StringRef Directive);
288 bool parseInternalDirectiveReallowModule();
290 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
292 bool eatComma(StringRef ErrorStr);
294 int matchCPURegisterName(StringRef Symbol);
296 int matchHWRegsRegisterName(StringRef Symbol);
298 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
300 int matchFPURegisterName(StringRef Name);
302 int matchFCCRegisterName(StringRef Name);
304 int matchACRegisterName(StringRef Name);
306 int matchMSA128RegisterName(StringRef Name);
308 int matchMSA128CtrlRegisterName(StringRef Name);
310 unsigned getReg(int RC, int RegNo);
312 unsigned getGPR(int RegNo);
314 /// Returns the internal register number for the current AT. Also checks if
315 /// the current AT is unavailable (set to $0) and gives an error if it is.
316 /// This should be used in pseudo-instruction expansions which need AT.
317 unsigned getATReg(SMLoc Loc);
319 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
320 SmallVectorImpl<MCInst> &Instructions);
322 // Helper function that checks if the value of a vector index is within the
323 // boundaries of accepted values for each RegisterKind
324 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
325 bool validateMSAIndex(int Val, int RegKind);
327 // Selects a new architecture by updating the FeatureBits with the necessary
328 // info including implied dependencies.
329 // Internally, it clears all the feature bits related to *any* architecture
330 // and selects the new one using the ToggleFeature functionality of the
331 // MCSubtargetInfo object that handles implied dependencies. The reason we
332 // clear all the arch related bits manually is because ToggleFeature only
333 // clears the features that imply the feature being cleared and not the
334 // features implied by the feature being cleared. This is easier to see
336 // --------------------------------------------------
337 // | Feature | Implies |
338 // | -------------------------------------------------|
339 // | FeatureMips1 | None |
340 // | FeatureMips2 | FeatureMips1 |
341 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
342 // | FeatureMips4 | FeatureMips3 |
344 // --------------------------------------------------
346 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
347 // FeatureMipsGP64 | FeatureMips1)
348 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
349 void selectArch(StringRef ArchFeature) {
350 FeatureBitset FeatureBits = STI.getFeatureBits();
351 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
352 STI.setFeatureBits(FeatureBits);
353 setAvailableFeatures(
354 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
355 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
358 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
359 if (!(STI.getFeatureBits()[Feature])) {
360 setAvailableFeatures(
361 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
362 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
366 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
367 if (STI.getFeatureBits()[Feature]) {
368 setAvailableFeatures(
369 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
370 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
374 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
375 setFeatureBits(Feature, FeatureString);
376 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
379 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
380 clearFeatureBits(Feature, FeatureString);
381 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
385 enum MipsMatchResultTy {
386 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
387 #define GET_OPERAND_DIAGNOSTIC_TYPES
388 #include "MipsGenAsmMatcher.inc"
389 #undef GET_OPERAND_DIAGNOSTIC_TYPES
392 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
393 const MCInstrInfo &MII, const MCTargetOptions &Options)
394 : MCTargetAsmParser(Options), STI(sti),
395 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
396 sti.getCPU(), Options)) {
397 MCAsmParserExtension::Initialize(parser);
399 parser.addAliasForDirective(".asciiz", ".asciz");
401 // Initialize the set of available features.
402 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
404 // Remember the initial assembler options. The user can not modify these.
405 AssemblerOptions.push_back(
406 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
408 // Create an assembler options environment for the user to modify.
409 AssemblerOptions.push_back(
410 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
412 getTargetStreamer().updateABIInfo(*this);
414 if (!isABI_O32() && !useOddSPReg() != 0)
415 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
420 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
422 IsCpRestoreSet = false;
423 CpRestoreOffset = -1;
425 Triple TheTriple(sti.getTargetTriple());
426 if ((TheTriple.getArch() == Triple::mips) ||
427 (TheTriple.getArch() == Triple::mips64))
428 IsLittleEndian = false;
430 IsLittleEndian = true;
433 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
434 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
436 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
437 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
438 const MipsABIInfo &getABI() const { return ABI; }
439 bool isABI_N32() const { return ABI.IsN32(); }
440 bool isABI_N64() const { return ABI.IsN64(); }
441 bool isABI_O32() const { return ABI.IsO32(); }
442 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
444 bool useOddSPReg() const {
445 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
448 bool inMicroMipsMode() const {
449 return STI.getFeatureBits()[Mips::FeatureMicroMips];
451 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
452 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
453 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
454 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
455 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
456 bool hasMips32() const {
457 return STI.getFeatureBits()[Mips::FeatureMips32];
459 bool hasMips64() const {
460 return STI.getFeatureBits()[Mips::FeatureMips64];
462 bool hasMips32r2() const {
463 return STI.getFeatureBits()[Mips::FeatureMips32r2];
465 bool hasMips64r2() const {
466 return STI.getFeatureBits()[Mips::FeatureMips64r2];
468 bool hasMips32r3() const {
469 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
471 bool hasMips64r3() const {
472 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
474 bool hasMips32r5() const {
475 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
477 bool hasMips64r5() const {
478 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
480 bool hasMips32r6() const {
481 return STI.getFeatureBits()[Mips::FeatureMips32r6];
483 bool hasMips64r6() const {
484 return STI.getFeatureBits()[Mips::FeatureMips64r6];
487 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
488 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
489 bool hasDSPR3() const { return STI.getFeatureBits()[Mips::FeatureDSPR3]; }
490 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
491 bool hasCnMips() const {
492 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
499 bool inMips16Mode() const {
500 return STI.getFeatureBits()[Mips::FeatureMips16];
503 bool useTraps() const {
504 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
507 bool useSoftFloat() const {
508 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
511 /// Warn if RegIndex is the same as the current AT.
512 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
514 void warnIfNoMacro(SMLoc Loc);
516 bool isLittle() const { return IsLittleEndian; }
522 /// MipsOperand - Instances of this class represent a parsed Mips machine
524 class MipsOperand : public MCParsedAsmOperand {
526 /// Broad categories of register classes
527 /// The exact class is finalized by the render method.
529 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
530 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
532 RegKind_FCC = 4, /// FCC
533 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
534 RegKind_MSACtrl = 16, /// MSA control registers
535 RegKind_COP2 = 32, /// COP2
536 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
538 RegKind_CCR = 128, /// CCR
539 RegKind_HWRegs = 256, /// HWRegs
540 RegKind_COP3 = 512, /// COP3
541 RegKind_COP0 = 1024, /// COP0
542 /// Potentially any (e.g. $1)
543 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
544 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
545 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
550 k_Immediate, /// An immediate (possibly involving symbol references)
551 k_Memory, /// Base + Offset Memory Address
552 k_PhysRegister, /// A physical register from the Mips namespace
553 k_RegisterIndex, /// A register index in one or more RegKind.
554 k_Token, /// A simple token
555 k_RegList, /// A physical register list
556 k_RegPair /// A pair of physical register
560 MipsOperand(KindTy K, MipsAsmParser &Parser)
561 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
564 /// For diagnostics, and checking the assembler temporary
565 MipsAsmParser &AsmParser;
573 unsigned Num; /// Register Number
577 unsigned Index; /// Index into the register class
578 RegKind Kind; /// Bitfield of the kinds it could possibly be
579 const MCRegisterInfo *RegInfo;
592 SmallVector<unsigned, 10> *List;
597 struct PhysRegOp PhysReg;
598 struct RegIdxOp RegIdx;
601 struct RegListOp RegList;
604 SMLoc StartLoc, EndLoc;
606 /// Internal constructor for register kinds
607 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
608 const MCRegisterInfo *RegInfo,
610 MipsAsmParser &Parser) {
611 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
612 Op->RegIdx.Index = Index;
613 Op->RegIdx.RegInfo = RegInfo;
614 Op->RegIdx.Kind = RegKind;
621 /// Coerce the register to GPR32 and return the real register for the current
623 unsigned getGPR32Reg() const {
624 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
625 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
626 unsigned ClassID = Mips::GPR32RegClassID;
627 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
630 /// Coerce the register to GPR32 and return the real register for the current
632 unsigned getGPRMM16Reg() const {
633 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
634 unsigned ClassID = Mips::GPR32RegClassID;
635 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
638 /// Coerce the register to GPR64 and return the real register for the current
640 unsigned getGPR64Reg() const {
641 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
642 unsigned ClassID = Mips::GPR64RegClassID;
643 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
647 /// Coerce the register to AFGR64 and return the real register for the current
649 unsigned getAFGR64Reg() const {
650 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
651 if (RegIdx.Index % 2 != 0)
652 AsmParser.Warning(StartLoc, "Float register should be even.");
653 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
654 .getRegister(RegIdx.Index / 2);
657 /// Coerce the register to FGR64 and return the real register for the current
659 unsigned getFGR64Reg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
661 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
662 .getRegister(RegIdx.Index);
665 /// Coerce the register to FGR32 and return the real register for the current
667 unsigned getFGR32Reg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
669 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
670 .getRegister(RegIdx.Index);
673 /// Coerce the register to FGRH32 and return the real register for the current
675 unsigned getFGRH32Reg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
677 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
678 .getRegister(RegIdx.Index);
681 /// Coerce the register to FCC and return the real register for the current
683 unsigned getFCCReg() const {
684 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
685 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
686 .getRegister(RegIdx.Index);
689 /// Coerce the register to MSA128 and return the real register for the current
691 unsigned getMSA128Reg() const {
692 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
693 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
695 unsigned ClassID = Mips::MSA128BRegClassID;
696 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
699 /// Coerce the register to MSACtrl and return the real register for the
701 unsigned getMSACtrlReg() const {
702 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
703 unsigned ClassID = Mips::MSACtrlRegClassID;
704 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
707 /// Coerce the register to COP0 and return the real register for the
709 unsigned getCOP0Reg() const {
710 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
711 unsigned ClassID = Mips::COP0RegClassID;
712 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
715 /// Coerce the register to COP2 and return the real register for the
717 unsigned getCOP2Reg() const {
718 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
719 unsigned ClassID = Mips::COP2RegClassID;
720 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
723 /// Coerce the register to COP3 and return the real register for the
725 unsigned getCOP3Reg() const {
726 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
727 unsigned ClassID = Mips::COP3RegClassID;
728 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
731 /// Coerce the register to ACC64DSP and return the real register for the
733 unsigned getACC64DSPReg() const {
734 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
735 unsigned ClassID = Mips::ACC64DSPRegClassID;
736 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
739 /// Coerce the register to HI32DSP and return the real register for the
741 unsigned getHI32DSPReg() const {
742 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
743 unsigned ClassID = Mips::HI32DSPRegClassID;
744 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
747 /// Coerce the register to LO32DSP and return the real register for the
749 unsigned getLO32DSPReg() const {
750 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
751 unsigned ClassID = Mips::LO32DSPRegClassID;
752 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
755 /// Coerce the register to CCR and return the real register for the
757 unsigned getCCRReg() const {
758 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
759 unsigned ClassID = Mips::CCRRegClassID;
760 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
763 /// Coerce the register to HWRegs and return the real register for the
765 unsigned getHWRegsReg() const {
766 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
767 unsigned ClassID = Mips::HWRegsRegClassID;
768 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
772 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
773 // Add as immediate when possible. Null MCExpr = 0.
775 Inst.addOperand(MCOperand::createImm(0));
776 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
777 Inst.addOperand(MCOperand::createImm(CE->getValue()));
779 Inst.addOperand(MCOperand::createExpr(Expr));
782 void addRegOperands(MCInst &Inst, unsigned N) const {
783 llvm_unreachable("Use a custom parser instead");
786 /// Render the operand to an MCInst as a GPR32
787 /// Asserts if the wrong number of operands are requested, or the operand
788 /// is not a k_RegisterIndex compatible with RegKind_GPR
789 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
790 assert(N == 1 && "Invalid number of operands!");
791 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
794 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
795 assert(N == 1 && "Invalid number of operands!");
796 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
799 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
800 assert(N == 1 && "Invalid number of operands!");
801 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
804 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
805 assert(N == 1 && "Invalid number of operands!");
806 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
809 /// Render the operand to an MCInst as a GPR64
810 /// Asserts if the wrong number of operands are requested, or the operand
811 /// is not a k_RegisterIndex compatible with RegKind_GPR
812 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
813 assert(N == 1 && "Invalid number of operands!");
814 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
817 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
818 assert(N == 1 && "Invalid number of operands!");
819 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
822 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 1 && "Invalid number of operands!");
824 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
827 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
828 assert(N == 1 && "Invalid number of operands!");
829 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
830 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
831 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
832 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
836 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
837 assert(N == 1 && "Invalid number of operands!");
838 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
841 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
842 assert(N == 1 && "Invalid number of operands!");
843 Inst.addOperand(MCOperand::createReg(getFCCReg()));
846 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
847 assert(N == 1 && "Invalid number of operands!");
848 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
851 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
852 assert(N == 1 && "Invalid number of operands!");
853 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
856 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
857 assert(N == 1 && "Invalid number of operands!");
858 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
861 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
862 assert(N == 1 && "Invalid number of operands!");
863 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
866 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
867 assert(N == 1 && "Invalid number of operands!");
868 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
871 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
872 assert(N == 1 && "Invalid number of operands!");
873 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
876 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
877 assert(N == 1 && "Invalid number of operands!");
878 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
881 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
882 assert(N == 1 && "Invalid number of operands!");
883 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
886 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
887 assert(N == 1 && "Invalid number of operands!");
888 Inst.addOperand(MCOperand::createReg(getCCRReg()));
891 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
892 assert(N == 1 && "Invalid number of operands!");
893 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
896 template <unsigned Bits, int Offset = 0>
897 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
898 assert(N == 1 && "Invalid number of operands!");
899 uint64_t Imm = getConstantImm() - Offset;
900 Imm &= (1 << Bits) - 1;
902 Inst.addOperand(MCOperand::createImm(Imm));
905 void addImmOperands(MCInst &Inst, unsigned N) const {
906 assert(N == 1 && "Invalid number of operands!");
907 const MCExpr *Expr = getImm();
911 void addMemOperands(MCInst &Inst, unsigned N) const {
912 assert(N == 2 && "Invalid number of operands!");
914 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
915 ? getMemBase()->getGPR64Reg()
916 : getMemBase()->getGPR32Reg()));
918 const MCExpr *Expr = getMemOff();
922 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
923 assert(N == 2 && "Invalid number of operands!");
925 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
927 const MCExpr *Expr = getMemOff();
931 void addRegListOperands(MCInst &Inst, unsigned N) const {
932 assert(N == 1 && "Invalid number of operands!");
934 for (auto RegNo : getRegList())
935 Inst.addOperand(MCOperand::createReg(RegNo));
938 void addRegPairOperands(MCInst &Inst, unsigned N) const {
939 assert(N == 2 && "Invalid number of operands!");
940 unsigned RegNo = getRegPair();
941 Inst.addOperand(MCOperand::createReg(RegNo++));
942 Inst.addOperand(MCOperand::createReg(RegNo));
945 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
946 assert(N == 2 && "Invalid number of operands!");
947 for (auto RegNo : getRegList())
948 Inst.addOperand(MCOperand::createReg(RegNo));
951 bool isReg() const override {
952 // As a special case until we sort out the definition of div/divu, pretend
953 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
954 if (isGPRAsmReg() && RegIdx.Index == 0)
957 return Kind == k_PhysRegister;
959 bool isRegIdx() const { return Kind == k_RegisterIndex; }
960 bool isImm() const override { return Kind == k_Immediate; }
961 bool isConstantImm() const {
962 return isImm() && dyn_cast<MCConstantExpr>(getImm());
964 bool isConstantImmz() const {
965 return isConstantImm() && getConstantImm() == 0;
967 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
968 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
970 template <unsigned Bits> bool isUImm() const {
971 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
973 bool isToken() const override {
974 // Note: It's not possible to pretend that other operand kinds are tokens.
975 // The matcher emitter checks tokens first.
976 return Kind == k_Token;
978 bool isMem() const override { return Kind == k_Memory; }
979 bool isConstantMemOff() const {
980 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
982 template <unsigned Bits> bool isMemWithSimmOffset() const {
983 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
984 && getMemBase()->isGPRAsmReg();
986 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
987 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
988 getMemBase()->isGPRAsmReg();
990 bool isMemWithGRPMM16Base() const {
991 return isMem() && getMemBase()->isMM16AsmReg();
993 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
994 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
995 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
997 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
998 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
999 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1000 && (getMemBase()->getGPR32Reg() == Mips::SP);
1002 bool isUImm5Lsl2() const {
1003 return (isImm() && isConstantImm() && isShiftedUInt<5, 2>(getConstantImm()));
1005 bool isRegList16() const {
1009 int Size = RegList.List->size();
1010 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
1011 RegList.List->back() != Mips::RA)
1014 int PrevReg = *RegList.List->begin();
1015 for (int i = 1; i < Size - 1; i++) {
1016 int Reg = (*(RegList.List))[i];
1017 if ( Reg != PrevReg + 1)
1024 bool isInvNum() const { return Kind == k_Immediate; }
1025 bool isLSAImm() const {
1026 if (!isConstantImm())
1028 int64_t Val = getConstantImm();
1029 return 1 <= Val && Val <= 4;
1031 bool isRegList() const { return Kind == k_RegList; }
1032 bool isMovePRegPair() const {
1033 if (Kind != k_RegList || RegList.List->size() != 2)
1036 unsigned R0 = RegList.List->front();
1037 unsigned R1 = RegList.List->back();
1039 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1040 (R0 == Mips::A1 && R1 == Mips::A3) ||
1041 (R0 == Mips::A2 && R1 == Mips::A3) ||
1042 (R0 == Mips::A0 && R1 == Mips::S5) ||
1043 (R0 == Mips::A0 && R1 == Mips::S6) ||
1044 (R0 == Mips::A0 && R1 == Mips::A1) ||
1045 (R0 == Mips::A0 && R1 == Mips::A2) ||
1046 (R0 == Mips::A0 && R1 == Mips::A3))
1052 StringRef getToken() const {
1053 assert(Kind == k_Token && "Invalid access!");
1054 return StringRef(Tok.Data, Tok.Length);
1056 bool isRegPair() const { return Kind == k_RegPair; }
1058 unsigned getReg() const override {
1059 // As a special case until we sort out the definition of div/divu, pretend
1060 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1061 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1062 RegIdx.Kind & RegKind_GPR)
1063 return getGPR32Reg(); // FIXME: GPR64 too
1065 assert(Kind == k_PhysRegister && "Invalid access!");
1069 const MCExpr *getImm() const {
1070 assert((Kind == k_Immediate) && "Invalid access!");
1074 int64_t getConstantImm() const {
1075 const MCExpr *Val = getImm();
1076 return static_cast<const MCConstantExpr *>(Val)->getValue();
1079 MipsOperand *getMemBase() const {
1080 assert((Kind == k_Memory) && "Invalid access!");
1084 const MCExpr *getMemOff() const {
1085 assert((Kind == k_Memory) && "Invalid access!");
1089 int64_t getConstantMemOff() const {
1090 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1093 const SmallVectorImpl<unsigned> &getRegList() const {
1094 assert((Kind == k_RegList) && "Invalid access!");
1095 return *(RegList.List);
1098 unsigned getRegPair() const {
1099 assert((Kind == k_RegPair) && "Invalid access!");
1100 return RegIdx.Index;
1103 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1104 MipsAsmParser &Parser) {
1105 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1106 Op->Tok.Data = Str.data();
1107 Op->Tok.Length = Str.size();
1113 /// Create a numeric register (e.g. $1). The exact register remains
1114 /// unresolved until an instruction successfully matches
1115 static std::unique_ptr<MipsOperand>
1116 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1117 SMLoc E, MipsAsmParser &Parser) {
1118 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1119 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1122 /// Create a register that is definitely a GPR.
1123 /// This is typically only used for named registers such as $gp.
1124 static std::unique_ptr<MipsOperand>
1125 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1126 MipsAsmParser &Parser) {
1127 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1130 /// Create a register that is definitely a FGR.
1131 /// This is typically only used for named registers such as $f0.
1132 static std::unique_ptr<MipsOperand>
1133 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1134 MipsAsmParser &Parser) {
1135 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1138 /// Create a register that is definitely a HWReg.
1139 /// This is typically only used for named registers such as $hwr_cpunum.
1140 static std::unique_ptr<MipsOperand>
1141 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1142 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1143 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1146 /// Create a register that is definitely an FCC.
1147 /// This is typically only used for named registers such as $fcc0.
1148 static std::unique_ptr<MipsOperand>
1149 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1150 MipsAsmParser &Parser) {
1151 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1154 /// Create a register that is definitely an ACC.
1155 /// This is typically only used for named registers such as $ac0.
1156 static std::unique_ptr<MipsOperand>
1157 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1158 MipsAsmParser &Parser) {
1159 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1162 /// Create a register that is definitely an MSA128.
1163 /// This is typically only used for named registers such as $w0.
1164 static std::unique_ptr<MipsOperand>
1165 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1166 SMLoc E, MipsAsmParser &Parser) {
1167 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1170 /// Create a register that is definitely an MSACtrl.
1171 /// This is typically only used for named registers such as $msaaccess.
1172 static std::unique_ptr<MipsOperand>
1173 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1174 SMLoc E, MipsAsmParser &Parser) {
1175 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1178 static std::unique_ptr<MipsOperand>
1179 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1180 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1187 static std::unique_ptr<MipsOperand>
1188 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1189 SMLoc E, MipsAsmParser &Parser) {
1190 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1191 Op->Mem.Base = Base.release();
1198 static std::unique_ptr<MipsOperand>
1199 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1200 MipsAsmParser &Parser) {
1201 assert (Regs.size() > 0 && "Empty list not allowed");
1203 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1204 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1205 Op->StartLoc = StartLoc;
1206 Op->EndLoc = EndLoc;
1210 static std::unique_ptr<MipsOperand>
1211 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1212 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1213 Op->RegIdx.Index = RegNo;
1219 bool isGPRAsmReg() const {
1220 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1222 bool isMM16AsmReg() const {
1223 if (!(isRegIdx() && RegIdx.Kind))
1225 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1226 || RegIdx.Index == 16 || RegIdx.Index == 17);
1228 bool isMM16AsmRegZero() const {
1229 if (!(isRegIdx() && RegIdx.Kind))
1231 return (RegIdx.Index == 0 ||
1232 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1233 RegIdx.Index == 17);
1235 bool isMM16AsmRegMoveP() const {
1236 if (!(isRegIdx() && RegIdx.Kind))
1238 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1239 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1241 bool isFGRAsmReg() const {
1242 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1243 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1245 bool isHWRegsAsmReg() const {
1246 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1248 bool isCCRAsmReg() const {
1249 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1251 bool isFCCAsmReg() const {
1252 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1254 if (!AsmParser.hasEightFccRegisters())
1255 return RegIdx.Index == 0;
1256 return RegIdx.Index <= 7;
1258 bool isACCAsmReg() const {
1259 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1261 bool isCOP0AsmReg() const {
1262 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1264 bool isCOP2AsmReg() const {
1265 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1267 bool isCOP3AsmReg() const {
1268 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1270 bool isMSA128AsmReg() const {
1271 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1273 bool isMSACtrlAsmReg() const {
1274 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1277 /// getStartLoc - Get the location of the first token of this operand.
1278 SMLoc getStartLoc() const override { return StartLoc; }
1279 /// getEndLoc - Get the location of the last token of this operand.
1280 SMLoc getEndLoc() const override { return EndLoc; }
1282 virtual ~MipsOperand() {
1290 delete RegList.List;
1291 case k_PhysRegister:
1292 case k_RegisterIndex:
1299 void print(raw_ostream &OS) const override {
1308 Mem.Base->print(OS);
1313 case k_PhysRegister:
1314 OS << "PhysReg<" << PhysReg.Num << ">";
1316 case k_RegisterIndex:
1317 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1324 for (auto Reg : (*RegList.List))
1329 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1333 }; // class MipsOperand
1337 extern const MCInstrDesc MipsInsts[];
1339 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1340 return MipsInsts[Opcode];
1343 static bool hasShortDelaySlot(unsigned Opcode) {
1346 case Mips::JALRS_MM:
1347 case Mips::JALRS16_MM:
1348 case Mips::BGEZALS_MM:
1349 case Mips::BLTZALS_MM:
1356 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1357 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1358 return &SRExpr->getSymbol();
1361 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1362 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1363 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1374 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1375 return getSingleMCSymbol(UExpr->getSubExpr());
1380 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1381 if (isa<MCSymbolRefExpr>(Expr))
1384 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1385 return countMCSymbolRefExpr(BExpr->getLHS()) +
1386 countMCSymbolRefExpr(BExpr->getRHS());
1388 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1389 return countMCSymbolRefExpr(UExpr->getSubExpr());
1395 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1396 SmallVectorImpl<MCInst> &Instructions) {
1398 tmpInst.setOpcode(Opcode);
1399 tmpInst.addOperand(MCOperand::createReg(Reg0));
1400 tmpInst.addOperand(Op1);
1401 tmpInst.setLoc(IDLoc);
1402 Instructions.push_back(tmpInst);
1405 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1406 SmallVectorImpl<MCInst> &Instructions) {
1407 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1410 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1411 SmallVectorImpl<MCInst> &Instructions) {
1412 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1415 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1416 SmallVectorImpl<MCInst> &Instructions) {
1418 tmpInst.setOpcode(Opcode);
1419 tmpInst.addOperand(MCOperand::createImm(Imm1));
1420 tmpInst.addOperand(MCOperand::createImm(Imm2));
1421 tmpInst.setLoc(IDLoc);
1422 Instructions.push_back(tmpInst);
1425 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1426 SmallVectorImpl<MCInst> &Instructions) {
1428 tmpInst.setOpcode(Opcode);
1429 tmpInst.addOperand(MCOperand::createReg(Reg0));
1430 tmpInst.setLoc(IDLoc);
1431 Instructions.push_back(tmpInst);
1434 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1435 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1437 tmpInst.setOpcode(Opcode);
1438 tmpInst.addOperand(MCOperand::createReg(Reg0));
1439 tmpInst.addOperand(MCOperand::createReg(Reg1));
1440 tmpInst.addOperand(Op2);
1441 tmpInst.setLoc(IDLoc);
1442 Instructions.push_back(tmpInst);
1445 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1446 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1447 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1451 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1452 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1453 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1457 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1458 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1459 if (ShiftAmount >= 32) {
1460 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1465 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1467 } // end anonymous namespace.
1469 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1470 SmallVectorImpl<MCInst> &Instructions) {
1471 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1472 bool ExpandedJalSym = false;
1476 if (MCID.isBranch() || MCID.isCall()) {
1477 const unsigned Opcode = Inst.getOpcode();
1487 assert(hasCnMips() && "instruction only valid for octeon cpus");
1494 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1495 Offset = Inst.getOperand(2);
1496 if (!Offset.isImm())
1497 break; // We'll deal with this situation later on when applying fixups.
1498 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1499 return Error(IDLoc, "branch target out of range");
1500 if (OffsetToAlignment(Offset.getImm(),
1501 1LL << (inMicroMipsMode() ? 1 : 2)))
1502 return Error(IDLoc, "branch to misaligned address");
1516 case Mips::BGEZAL_MM:
1517 case Mips::BLTZAL_MM:
1520 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1521 Offset = Inst.getOperand(1);
1522 if (!Offset.isImm())
1523 break; // We'll deal with this situation later on when applying fixups.
1524 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1525 return Error(IDLoc, "branch target out of range");
1526 if (OffsetToAlignment(Offset.getImm(),
1527 1LL << (inMicroMipsMode() ? 1 : 2)))
1528 return Error(IDLoc, "branch to misaligned address");
1530 case Mips::BEQZ16_MM:
1531 case Mips::BEQZC16_MMR6:
1532 case Mips::BNEZ16_MM:
1533 case Mips::BNEZC16_MMR6:
1534 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1535 Offset = Inst.getOperand(1);
1536 if (!Offset.isImm())
1537 break; // We'll deal with this situation later on when applying fixups.
1538 if (!isInt<8>(Offset.getImm()))
1539 return Error(IDLoc, "branch target out of range");
1540 if (OffsetToAlignment(Offset.getImm(), 2LL))
1541 return Error(IDLoc, "branch to misaligned address");
1546 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1547 // We still accept it but it is a normal nop.
1548 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1549 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1550 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1555 const unsigned Opcode = Inst.getOpcode();
1567 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1568 // The offset is handled above
1569 Opnd = Inst.getOperand(1);
1571 return Error(IDLoc, "expected immediate operand kind");
1572 Imm = Opnd.getImm();
1573 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1574 Opcode == Mips::BBIT1 ? 63 : 31))
1575 return Error(IDLoc, "immediate operand value out of range");
1577 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1579 Inst.getOperand(1).setImm(Imm - 32);
1587 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1589 Opnd = Inst.getOperand(3);
1591 return Error(IDLoc, "expected immediate operand kind");
1592 Imm = Opnd.getImm();
1593 if (Imm < 0 || Imm > 31)
1594 return Error(IDLoc, "immediate operand value out of range");
1596 Opnd = Inst.getOperand(2);
1598 return Error(IDLoc, "expected immediate operand kind");
1599 Imm = Opnd.getImm();
1600 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1601 Opcode == Mips::EXTS ? 63 : 31))
1602 return Error(IDLoc, "immediate operand value out of range");
1604 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1605 Inst.getOperand(2).setImm(Imm - 32);
1611 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1612 Opnd = Inst.getOperand(2);
1614 return Error(IDLoc, "expected immediate operand kind");
1615 Imm = Opnd.getImm();
1616 if (!isInt<10>(Imm))
1617 return Error(IDLoc, "immediate operand value out of range");
1622 // This expansion is not in a function called by tryExpandInstruction()
1623 // because the pseudo-instruction doesn't have a distinct opcode.
1624 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1626 warnIfNoMacro(IDLoc);
1628 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1630 // We can do this expansion if there's only 1 symbol in the argument
1632 if (countMCSymbolRefExpr(JalExpr) > 1)
1633 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1635 // FIXME: This is checking the expression can be handled by the later stages
1636 // of the assembler. We ought to leave it to those later stages but
1637 // we can't do that until we stop evaluateRelocExpr() rewriting the
1638 // expressions into non-equivalent forms.
1639 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1641 // FIXME: Add support for label+offset operands (currently causes an error).
1642 // FIXME: Add support for forward-declared local symbols.
1643 // FIXME: Add expansion for when the LargeGOT option is enabled.
1644 if (JalSym->isInSection() || JalSym->isTemporary()) {
1646 // If it's a local symbol and the O32 ABI is being used, we expand to:
1648 // R_(MICRO)MIPS_GOT16 label
1649 // addiu $25, $25, 0
1650 // R_(MICRO)MIPS_LO16 label
1652 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1653 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1655 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1656 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1657 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1658 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1659 } else if (isABI_N32() || isABI_N64()) {
1660 // If it's a local symbol and the N32/N64 ABIs are being used,
1662 // lw/ld $25, 0($gp)
1663 // R_(MICRO)MIPS_GOT_DISP label
1665 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1667 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1668 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1671 // If it's an external/weak symbol, we expand to:
1672 // lw/ld $25, 0($gp)
1673 // R_(MICRO)MIPS_CALL16 label
1675 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1677 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1678 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1682 if (IsCpRestoreSet && inMicroMipsMode())
1683 JalrInst.setOpcode(Mips::JALRS_MM);
1685 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1686 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1687 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1689 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1690 // This relocation is supposed to be an optimization hint for the linker
1691 // and is not necessary for correctness.
1694 ExpandedJalSym = true;
1697 if (MCID.mayLoad() || MCID.mayStore()) {
1698 // Check the offset of memory operand, if it is a symbol
1699 // reference or immediate we may have to expand instructions.
1700 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1701 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1702 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1703 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1704 MCOperand &Op = Inst.getOperand(i);
1706 int MemOffset = Op.getImm();
1707 if (MemOffset < -32768 || MemOffset > 32767) {
1708 // Offset can't exceed 16bit value.
1709 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1712 } else if (Op.isExpr()) {
1713 const MCExpr *Expr = Op.getExpr();
1714 if (Expr->getKind() == MCExpr::SymbolRef) {
1715 const MCSymbolRefExpr *SR =
1716 static_cast<const MCSymbolRefExpr *>(Expr);
1717 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1719 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1722 } else if (!isEvaluated(Expr)) {
1723 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1731 if (inMicroMipsMode()) {
1732 if (MCID.mayLoad()) {
1733 // Try to create 16-bit GP relative load instruction.
1734 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1735 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1736 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1737 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1738 MCOperand &Op = Inst.getOperand(i);
1740 int MemOffset = Op.getImm();
1741 MCOperand &DstReg = Inst.getOperand(0);
1742 MCOperand &BaseReg = Inst.getOperand(1);
1743 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1744 getContext().getRegisterInfo()->getRegClass(
1745 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1746 (BaseReg.getReg() == Mips::GP ||
1747 BaseReg.getReg() == Mips::GP_64)) {
1749 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1750 IDLoc, Instructions);
1758 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1763 switch (Inst.getOpcode()) {
1766 case Mips::ADDIUS5_MM:
1767 Opnd = Inst.getOperand(2);
1769 return Error(IDLoc, "expected immediate operand kind");
1770 Imm = Opnd.getImm();
1771 if (Imm < -8 || Imm > 7)
1772 return Error(IDLoc, "immediate operand value out of range");
1774 case Mips::ADDIUSP_MM:
1775 Opnd = Inst.getOperand(0);
1777 return Error(IDLoc, "expected immediate operand kind");
1778 Imm = Opnd.getImm();
1779 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1781 return Error(IDLoc, "immediate operand value out of range");
1783 case Mips::SLL16_MM:
1784 case Mips::SRL16_MM:
1785 Opnd = Inst.getOperand(2);
1787 return Error(IDLoc, "expected immediate operand kind");
1788 Imm = Opnd.getImm();
1789 if (Imm < 1 || Imm > 8)
1790 return Error(IDLoc, "immediate operand value out of range");
1793 Opnd = Inst.getOperand(1);
1795 return Error(IDLoc, "expected immediate operand kind");
1796 Imm = Opnd.getImm();
1797 if (Imm < -1 || Imm > 126)
1798 return Error(IDLoc, "immediate operand value out of range");
1800 case Mips::ADDIUR2_MM:
1801 Opnd = Inst.getOperand(2);
1803 return Error(IDLoc, "expected immediate operand kind");
1804 Imm = Opnd.getImm();
1805 if (!(Imm == 1 || Imm == -1 ||
1806 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1807 return Error(IDLoc, "immediate operand value out of range");
1809 case Mips::ADDIUR1SP_MM:
1810 Opnd = Inst.getOperand(1);
1812 return Error(IDLoc, "expected immediate operand kind");
1813 Imm = Opnd.getImm();
1814 if (OffsetToAlignment(Imm, 4LL))
1815 return Error(IDLoc, "misaligned immediate operand value");
1816 if (Imm < 0 || Imm > 255)
1817 return Error(IDLoc, "immediate operand value out of range");
1819 case Mips::ANDI16_MM:
1820 Opnd = Inst.getOperand(2);
1822 return Error(IDLoc, "expected immediate operand kind");
1823 Imm = Opnd.getImm();
1824 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1825 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1826 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1827 return Error(IDLoc, "immediate operand value out of range");
1829 case Mips::LBU16_MM:
1830 Opnd = Inst.getOperand(2);
1832 return Error(IDLoc, "expected immediate operand kind");
1833 Imm = Opnd.getImm();
1834 if (Imm < -1 || Imm > 14)
1835 return Error(IDLoc, "immediate operand value out of range");
1844 Opnd = Inst.getOperand(2);
1846 return Error(IDLoc, "expected immediate operand kind");
1847 Imm = Opnd.getImm();
1848 if (Imm < 0 || Imm > 15)
1849 return Error(IDLoc, "immediate operand value out of range");
1851 case Mips::LHU16_MM:
1853 Opnd = Inst.getOperand(2);
1855 return Error(IDLoc, "expected immediate operand kind");
1856 Imm = Opnd.getImm();
1857 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1858 return Error(IDLoc, "immediate operand value out of range");
1862 Opnd = Inst.getOperand(2);
1864 return Error(IDLoc, "expected immediate operand kind");
1865 Imm = Opnd.getImm();
1866 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1867 return Error(IDLoc, "immediate operand value out of range");
1869 case Mips::PREFX_MM:
1872 Opnd = Inst.getOperand(2);
1874 return Error(IDLoc, "expected immediate operand kind");
1875 Imm = Opnd.getImm();
1876 if (!isUInt<5>(Imm))
1877 return Error(IDLoc, "immediate operand value out of range");
1879 case Mips::ADDIUPC_MM:
1880 MCOperand Opnd = Inst.getOperand(1);
1882 return Error(IDLoc, "expected immediate operand kind");
1883 int Imm = Opnd.getImm();
1884 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1885 return Error(IDLoc, "immediate operand value out of range");
1890 MacroExpanderResultTy ExpandResult =
1891 tryExpandInstruction(Inst, IDLoc, Instructions);
1892 switch (ExpandResult) {
1894 Instructions.push_back(Inst);
1902 // If this instruction has a delay slot and .set reorder is active,
1903 // emit a NOP after it.
1904 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1905 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1907 if ((Inst.getOpcode() == Mips::JalOneReg ||
1908 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1909 isPicAndNotNxxAbi()) {
1910 if (IsCpRestoreSet) {
1911 // We need a NOP between the JALR and the LW:
1912 // If .set reorder has been used, we've already emitted a NOP.
1913 // If .set noreorder has been used, we need to emit a NOP at this point.
1914 if (!AssemblerOptions.back()->isReorder())
1915 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1917 // Load the $gp from the stack.
1918 SmallVector<MCInst, 3> LoadInsts;
1919 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1922 for (const MCInst &Inst : LoadInsts)
1923 Instructions.push_back(Inst);
1926 Warning(IDLoc, "no .cprestore used in PIC mode");
1932 MipsAsmParser::MacroExpanderResultTy
1933 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
1934 SmallVectorImpl<MCInst> &Instructions) {
1935 switch (Inst.getOpcode()) {
1937 return MER_NotAMacro;
1938 case Mips::LoadImm32:
1939 return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
1941 case Mips::LoadImm64:
1942 return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
1944 case Mips::LoadAddrImm32:
1945 case Mips::LoadAddrImm64:
1946 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1947 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1948 "expected immediate operand kind");
1950 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
1952 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1956 case Mips::LoadAddrReg32:
1957 case Mips::LoadAddrReg64:
1958 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1959 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1960 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1961 "expected immediate operand kind");
1963 return expandLoadAddress(Inst.getOperand(0).getReg(),
1964 Inst.getOperand(1).getReg(), Inst.getOperand(2),
1965 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
1969 case Mips::B_MM_Pseudo:
1970 case Mips::B_MMR6_Pseudo:
1971 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
1975 return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
1977 case Mips::JalOneReg:
1978 case Mips::JalTwoReg:
1979 return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
1983 return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2000 case Mips::BLTImmMacro:
2001 case Mips::BLEImmMacro:
2002 case Mips::BGEImmMacro:
2003 case Mips::BGTImmMacro:
2004 case Mips::BLTUImmMacro:
2005 case Mips::BLEUImmMacro:
2006 case Mips::BGEUImmMacro:
2007 case Mips::BGTUImmMacro:
2008 case Mips::BLTLImmMacro:
2009 case Mips::BLELImmMacro:
2010 case Mips::BGELImmMacro:
2011 case Mips::BGTLImmMacro:
2012 case Mips::BLTULImmMacro:
2013 case Mips::BLEULImmMacro:
2014 case Mips::BGEULImmMacro:
2015 case Mips::BGTULImmMacro:
2016 return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2018 case Mips::SDivMacro:
2019 return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2021 case Mips::DSDivMacro:
2022 return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2024 case Mips::UDivMacro:
2025 return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2027 case Mips::DUDivMacro:
2028 return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2031 return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2033 return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2035 return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2037 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2043 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2044 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2045 int64_t ImmValue = Inst.getOperand(2).getImm();
2046 if (isInt<16>(ImmValue))
2047 return MER_NotAMacro;
2048 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2051 return MER_NotAMacro;
2055 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2056 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2057 int64_t ImmValue = Inst.getOperand(2).getImm();
2058 if (isUInt<16>(ImmValue))
2059 return MER_NotAMacro;
2060 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2063 return MER_NotAMacro;
2067 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2068 SmallVectorImpl<MCInst> &Instructions) {
2069 // Create a JALR instruction which is going to replace the pseudo-JAL.
2071 JalrInst.setLoc(IDLoc);
2072 const MCOperand FirstRegOp = Inst.getOperand(0);
2073 const unsigned Opcode = Inst.getOpcode();
2075 if (Opcode == Mips::JalOneReg) {
2076 // jal $rs => jalr $rs
2077 if (IsCpRestoreSet && inMicroMipsMode()) {
2078 JalrInst.setOpcode(Mips::JALRS16_MM);
2079 JalrInst.addOperand(FirstRegOp);
2080 } else if (inMicroMipsMode()) {
2081 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2082 JalrInst.addOperand(FirstRegOp);
2084 JalrInst.setOpcode(Mips::JALR);
2085 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2086 JalrInst.addOperand(FirstRegOp);
2088 } else if (Opcode == Mips::JalTwoReg) {
2089 // jal $rd, $rs => jalr $rd, $rs
2090 if (IsCpRestoreSet && inMicroMipsMode())
2091 JalrInst.setOpcode(Mips::JALRS_MM);
2093 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2094 JalrInst.addOperand(FirstRegOp);
2095 const MCOperand SecondRegOp = Inst.getOperand(1);
2096 JalrInst.addOperand(SecondRegOp);
2098 Instructions.push_back(JalrInst);
2100 // If .set reorder is active and branch instruction has a delay slot,
2101 // emit a NOP after it.
2102 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2103 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2104 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2110 /// Can the value be represented by a unsigned N-bit value and a shift left?
2111 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2112 unsigned BitNum = findFirstSet(x);
2114 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2117 /// Load (or add) an immediate into a register.
2119 /// @param ImmValue The immediate to load.
2120 /// @param DstReg The register that will hold the immediate.
2121 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2122 /// for a simple initialization.
2123 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2124 /// @param IsAddress True if the immediate represents an address. False if it
2126 /// @param IDLoc Location of the immediate in the source file.
2127 /// @param Instructions The instructions emitted by this expansion.
2128 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2129 unsigned SrcReg, bool Is32BitImm,
2130 bool IsAddress, SMLoc IDLoc,
2131 SmallVectorImpl<MCInst> &Instructions) {
2132 if (!Is32BitImm && !isGP64bit()) {
2133 Error(IDLoc, "instruction requires a 64-bit architecture");
2138 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2139 // Sign extend up to 64-bit so that the predicates match the hardware
2140 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2142 ImmValue = SignExtend64<32>(ImmValue);
2144 Error(IDLoc, "instruction requires a 32-bit immediate");
2149 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2150 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2152 bool UseSrcReg = false;
2153 if (SrcReg != Mips::NoRegister)
2156 unsigned TmpReg = DstReg;
2157 if (UseSrcReg && (DstReg == SrcReg)) {
2158 // At this point we need AT to perform the expansions and we exit if it is
2160 unsigned ATReg = getATReg(IDLoc);
2166 if (isInt<16>(ImmValue)) {
2170 // This doesn't quite follow the usual ABI expectations for N32 but matches
2171 // traditional assembler behaviour. N32 would normally use addiu for both
2172 // integers and addresses.
2173 if (IsAddress && !Is32BitImm) {
2174 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2178 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2182 if (isUInt<16>(ImmValue)) {
2183 unsigned TmpReg = DstReg;
2184 if (SrcReg == DstReg) {
2185 TmpReg = getATReg(IDLoc);
2190 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2192 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2196 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2197 warnIfNoMacro(IDLoc);
2199 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2200 uint16_t Bits15To0 = ImmValue & 0xffff;
2202 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2203 // Traditional behaviour seems to special case this particular value. It's
2204 // not clear why other masks are handled differently.
2205 if (ImmValue == 0xffffffff) {
2206 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2207 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2209 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2213 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2215 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2216 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2218 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2220 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2224 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2226 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2228 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2232 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2234 Error(IDLoc, "instruction requires a 32-bit immediate");
2238 // Traditionally, these immediates are shifted as little as possible and as
2239 // such we align the most significant bit to bit 15 of our temporary.
2240 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2241 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2242 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2243 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2244 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2245 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2248 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2253 warnIfNoMacro(IDLoc);
2255 // The remaining case is packed with a sequence of dsll and ori with zeros
2256 // being omitted and any neighbouring dsll's being coalesced.
2257 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2259 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2260 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2261 IDLoc, Instructions))
2264 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2265 // skip it and defer the shift to the next chunk.
2266 unsigned ShiftCarriedForwards = 16;
2267 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2268 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2270 if (ImmChunk != 0) {
2271 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2273 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2274 ShiftCarriedForwards = 0;
2277 ShiftCarriedForwards += 16;
2279 ShiftCarriedForwards -= 16;
2281 // Finish any remaining shifts left by trailing zeros.
2282 if (ShiftCarriedForwards)
2283 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2287 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2292 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2293 SmallVectorImpl<MCInst> &Instructions) {
2294 const MCOperand &ImmOp = Inst.getOperand(1);
2295 assert(ImmOp.isImm() && "expected immediate operand kind");
2296 const MCOperand &DstRegOp = Inst.getOperand(0);
2297 assert(DstRegOp.isReg() && "expected register operand kind");
2299 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2300 Is32BitImm, false, IDLoc, Instructions))
2306 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2307 const MCOperand &Offset,
2308 bool Is32BitAddress, SMLoc IDLoc,
2309 SmallVectorImpl<MCInst> &Instructions) {
2310 // la can't produce a usable address when addresses are 64-bit.
2311 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2312 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2313 // We currently can't do this because we depend on the equality
2314 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2315 Error(IDLoc, "la used to load 64-bit address");
2316 // Continue as if we had 'dla' instead.
2317 Is32BitAddress = false;
2320 // dla requires 64-bit addresses.
2321 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2322 Error(IDLoc, "instruction requires a 64-bit architecture");
2326 if (!Offset.isImm())
2327 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2328 Is32BitAddress, IDLoc, Instructions);
2330 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2331 IDLoc, Instructions);
2334 bool MipsAsmParser::loadAndAddSymbolAddress(
2335 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2336 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2337 warnIfNoMacro(IDLoc);
2339 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2340 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2341 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2342 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2343 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2345 bool UseSrcReg = SrcReg != Mips::NoRegister;
2347 // This is the 64-bit symbol address expansion.
2348 if (ABI.ArePtrs64bit() && isGP64bit()) {
2349 // We always need AT for the 64-bit expansion.
2350 // If it is not available we exit.
2351 unsigned ATReg = getATReg(IDLoc);
2355 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2356 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2357 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2358 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2360 if (UseSrcReg && (DstReg == SrcReg)) {
2361 // If $rs is the same as $rd:
2362 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2363 // daddiu $at, $at, %higher(sym)
2364 // dsll $at, $at, 16
2365 // daddiu $at, $at, %hi(sym)
2366 // dsll $at, $at, 16
2367 // daddiu $at, $at, %lo(sym)
2368 // daddu $rd, $at, $rd
2369 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2371 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2372 IDLoc, Instructions);
2373 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2374 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2376 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2377 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2379 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2384 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2385 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2386 // lui $at, %hi(sym)
2387 // daddiu $rd, $rd, %higher(sym)
2388 // daddiu $at, $at, %lo(sym)
2389 // dsll32 $rd, $rd, 0
2390 // daddu $rd, $rd, $at
2391 // (daddu $rd, $rd, $rs)
2392 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2394 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2396 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2397 IDLoc, Instructions);
2398 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2400 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2401 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2403 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2408 // And now, the 32-bit symbol address expansion:
2409 // If $rs is the same as $rd:
2410 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2411 // ori $at, $at, %lo(sym)
2412 // addu $rd, $at, $rd
2413 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2414 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2415 // ori $rd, $rd, %lo(sym)
2416 // (addu $rd, $rd, $rs)
2417 unsigned TmpReg = DstReg;
2418 if (UseSrcReg && (DstReg == SrcReg)) {
2419 // If $rs is the same as $rd, we need to use AT.
2420 // If it is not available we exit.
2421 unsigned ATReg = getATReg(IDLoc);
2427 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2428 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2432 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2434 assert(DstReg == TmpReg);
2439 bool MipsAsmParser::expandUncondBranchMMPseudo(
2440 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2441 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2442 "unexpected number of operands");
2444 MCOperand Offset = Inst.getOperand(0);
2445 if (Offset.isExpr()) {
2447 Inst.setOpcode(Mips::BEQ_MM);
2448 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2449 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2450 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2452 assert(Offset.isImm() && "expected immediate operand kind");
2453 if (isInt<11>(Offset.getImm())) {
2454 // If offset fits into 11 bits then this instruction becomes microMIPS
2455 // 16-bit unconditional branch instruction.
2456 if (inMicroMipsMode())
2457 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2459 if (!isInt<17>(Offset.getImm()))
2460 Error(IDLoc, "branch target out of range");
2461 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2462 Error(IDLoc, "branch to misaligned address");
2464 Inst.setOpcode(Mips::BEQ_MM);
2465 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2466 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2467 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2470 Instructions.push_back(Inst);
2472 // If .set reorder is active and branch instruction has a delay slot,
2473 // emit a NOP after it.
2474 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2475 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2476 createNop(true, IDLoc, Instructions);
2481 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2482 SmallVectorImpl<MCInst> &Instructions) {
2483 const MCOperand &DstRegOp = Inst.getOperand(0);
2484 assert(DstRegOp.isReg() && "expected register operand kind");
2486 const MCOperand &ImmOp = Inst.getOperand(1);
2487 assert(ImmOp.isImm() && "expected immediate operand kind");
2489 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2490 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2492 unsigned OpCode = 0;
2493 switch(Inst.getOpcode()) {
2501 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2505 int64_t ImmValue = ImmOp.getImm();
2507 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2510 warnIfNoMacro(IDLoc);
2512 unsigned ATReg = getATReg(IDLoc);
2516 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2517 IDLoc, Instructions))
2520 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2525 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2526 SmallVectorImpl<MCInst> &Instructions,
2527 bool isLoad, bool isImmOpnd) {
2528 unsigned ImmOffset, HiOffset, LoOffset;
2529 const MCExpr *ExprOffset;
2531 // 1st operand is either the source or destination register.
2532 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2533 unsigned RegOpNum = Inst.getOperand(0).getReg();
2534 // 2nd operand is the base register.
2535 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2536 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2537 // 3rd operand is either an immediate or expression.
2539 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2540 ImmOffset = Inst.getOperand(2).getImm();
2541 LoOffset = ImmOffset & 0x0000ffff;
2542 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2543 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2544 if (LoOffset & 0x8000)
2547 ExprOffset = Inst.getOperand(2).getExpr();
2548 // These are some of the types of expansions we perform here:
2549 // 1) lw $8, sym => lui $8, %hi(sym)
2550 // lw $8, %lo(sym)($8)
2551 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2553 // lw $8, %lo(offset)($9)
2554 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2556 // lw $8, %lo(offset)($at)
2557 // 4) sw $8, sym => lui $at, %hi(sym)
2558 // sw $8, %lo(sym)($at)
2559 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2561 // sw $8, %lo(offset)($at)
2562 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2563 // ldc1 $f0, %lo(sym)($at)
2565 // For load instructions we can use the destination register as a temporary
2566 // if base and dst are different (examples 1 and 2) and if the base register
2567 // is general purpose otherwise we must use $at (example 6) and error if it's
2568 // not available. For stores we must use $at (examples 4 and 5) because we
2569 // must not clobber the source register setting up the offset.
2570 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2571 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2572 unsigned RegClassIDOp0 =
2573 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2574 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2575 (RegClassIDOp0 == Mips::GPR64RegClassID);
2576 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2577 TmpRegNum = RegOpNum;
2579 // At this point we need AT to perform the expansions and we exit if it is
2581 TmpRegNum = getATReg(IDLoc);
2586 emitRX(Mips::LUi, TmpRegNum,
2587 isImmOpnd ? MCOperand::createImm(HiOffset)
2588 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2589 IDLoc, Instructions);
2590 // Add temp register to base.
2591 if (BaseRegNum != Mips::ZERO)
2592 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2593 // And finally, create original instruction with low part
2594 // of offset and new base.
2595 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2597 ? MCOperand::createImm(LoOffset)
2598 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2599 IDLoc, Instructions);
2603 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2604 SmallVectorImpl<MCInst> &Instructions) {
2605 unsigned OpNum = Inst.getNumOperands();
2606 unsigned Opcode = Inst.getOpcode();
2607 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2609 assert (Inst.getOperand(OpNum - 1).isImm() &&
2610 Inst.getOperand(OpNum - 2).isReg() &&
2611 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2613 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2614 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2615 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2616 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2617 // It can be implemented as SWM16 or LWM16 instruction.
2618 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2620 Inst.setOpcode(NewOpcode);
2621 Instructions.push_back(Inst);
2625 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2626 SmallVectorImpl<MCInst> &Instructions) {
2627 bool EmittedNoMacroWarning = false;
2628 unsigned PseudoOpcode = Inst.getOpcode();
2629 unsigned SrcReg = Inst.getOperand(0).getReg();
2630 const MCOperand &TrgOp = Inst.getOperand(1);
2631 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2633 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2634 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2638 TrgReg = TrgOp.getReg();
2639 else if (TrgOp.isImm()) {
2640 warnIfNoMacro(IDLoc);
2641 EmittedNoMacroWarning = true;
2643 TrgReg = getATReg(IDLoc);
2647 switch(PseudoOpcode) {
2649 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2650 case Mips::BLTImmMacro:
2651 PseudoOpcode = Mips::BLT;
2653 case Mips::BLEImmMacro:
2654 PseudoOpcode = Mips::BLE;
2656 case Mips::BGEImmMacro:
2657 PseudoOpcode = Mips::BGE;
2659 case Mips::BGTImmMacro:
2660 PseudoOpcode = Mips::BGT;
2662 case Mips::BLTUImmMacro:
2663 PseudoOpcode = Mips::BLTU;
2665 case Mips::BLEUImmMacro:
2666 PseudoOpcode = Mips::BLEU;
2668 case Mips::BGEUImmMacro:
2669 PseudoOpcode = Mips::BGEU;
2671 case Mips::BGTUImmMacro:
2672 PseudoOpcode = Mips::BGTU;
2674 case Mips::BLTLImmMacro:
2675 PseudoOpcode = Mips::BLTL;
2677 case Mips::BLELImmMacro:
2678 PseudoOpcode = Mips::BLEL;
2680 case Mips::BGELImmMacro:
2681 PseudoOpcode = Mips::BGEL;
2683 case Mips::BGTLImmMacro:
2684 PseudoOpcode = Mips::BGTL;
2686 case Mips::BLTULImmMacro:
2687 PseudoOpcode = Mips::BLTUL;
2689 case Mips::BLEULImmMacro:
2690 PseudoOpcode = Mips::BLEUL;
2692 case Mips::BGEULImmMacro:
2693 PseudoOpcode = Mips::BGEUL;
2695 case Mips::BGTULImmMacro:
2696 PseudoOpcode = Mips::BGTUL;
2700 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2701 false, IDLoc, Instructions))
2705 switch (PseudoOpcode) {
2710 AcceptsEquality = false;
2711 ReverseOrderSLT = false;
2712 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2713 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2714 ZeroSrcOpcode = Mips::BGTZ;
2715 ZeroTrgOpcode = Mips::BLTZ;
2721 AcceptsEquality = true;
2722 ReverseOrderSLT = true;
2723 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2724 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2725 ZeroSrcOpcode = Mips::BGEZ;
2726 ZeroTrgOpcode = Mips::BLEZ;
2732 AcceptsEquality = true;
2733 ReverseOrderSLT = false;
2734 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2735 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2736 ZeroSrcOpcode = Mips::BLEZ;
2737 ZeroTrgOpcode = Mips::BGEZ;
2743 AcceptsEquality = false;
2744 ReverseOrderSLT = true;
2745 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2746 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2747 ZeroSrcOpcode = Mips::BLTZ;
2748 ZeroTrgOpcode = Mips::BGTZ;
2751 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2754 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2755 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2756 if (IsSrcRegZero && IsTrgRegZero) {
2757 // FIXME: All of these Opcode-specific if's are needed for compatibility
2758 // with GAS' behaviour. However, they may not generate the most efficient
2759 // code in some circumstances.
2760 if (PseudoOpcode == Mips::BLT) {
2761 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2765 if (PseudoOpcode == Mips::BLE) {
2766 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2768 Warning(IDLoc, "branch is always taken");
2771 if (PseudoOpcode == Mips::BGE) {
2772 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2774 Warning(IDLoc, "branch is always taken");
2777 if (PseudoOpcode == Mips::BGT) {
2778 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2782 if (PseudoOpcode == Mips::BGTU) {
2783 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2784 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2787 if (AcceptsEquality) {
2788 // If both registers are $0 and the pseudo-branch accepts equality, it
2789 // will always be taken, so we emit an unconditional branch.
2790 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2791 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2792 Warning(IDLoc, "branch is always taken");
2795 // If both registers are $0 and the pseudo-branch does not accept
2796 // equality, it will never be taken, so we don't have to emit anything.
2799 if (IsSrcRegZero || IsTrgRegZero) {
2800 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2801 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2802 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2803 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2804 // the pseudo-branch will never be taken, so we don't emit anything.
2805 // This only applies to unsigned pseudo-branches.
2808 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2809 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2810 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2811 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2812 // the pseudo-branch will always be taken, so we emit an unconditional
2814 // This only applies to unsigned pseudo-branches.
2815 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2816 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2817 Warning(IDLoc, "branch is always taken");
2821 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2822 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2823 // the pseudo-branch will be taken only when the non-zero register is
2824 // different from 0, so we emit a BNEZ.
2826 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2827 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2828 // the pseudo-branch will be taken only when the non-zero register is
2829 // equal to 0, so we emit a BEQZ.
2831 // Because only BLEU and BGEU branch on equality, we can use the
2832 // AcceptsEquality variable to decide when to emit the BEQZ.
2833 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2834 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2835 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2838 // If we have a signed pseudo-branch and one of the registers is $0,
2839 // we can use an appropriate compare-to-zero branch. We select which one
2840 // to use in the switch statement above.
2841 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2842 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2843 IDLoc, Instructions);
2847 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2848 // expansions. If it is not available, we return.
2849 unsigned ATRegNum = getATReg(IDLoc);
2853 if (!EmittedNoMacroWarning)
2854 warnIfNoMacro(IDLoc);
2856 // SLT fits well with 2 of our 4 pseudo-branches:
2857 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2858 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2859 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2860 // This is accomplished by using a BNEZ with the result of the SLT.
2862 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2863 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2864 // Because only BGE and BLE branch on equality, we can use the
2865 // AcceptsEquality variable to decide when to emit the BEQZ.
2866 // Note that the order of the SLT arguments doesn't change between
2869 // The same applies to the unsigned variants, except that SLTu is used
2871 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2872 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2873 IDLoc, Instructions);
2875 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2876 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2877 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2882 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2883 SmallVectorImpl<MCInst> &Instructions,
2884 const bool IsMips64, const bool Signed) {
2885 if (hasMips32r6()) {
2886 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2890 warnIfNoMacro(IDLoc);
2892 const MCOperand &RsRegOp = Inst.getOperand(0);
2893 assert(RsRegOp.isReg() && "expected register operand kind");
2894 unsigned RsReg = RsRegOp.getReg();
2896 const MCOperand &RtRegOp = Inst.getOperand(1);
2897 assert(RtRegOp.isReg() && "expected register operand kind");
2898 unsigned RtReg = RtRegOp.getReg();
2903 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2904 ZeroReg = Mips::ZERO_64;
2906 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2907 ZeroReg = Mips::ZERO;
2910 bool UseTraps = useTraps();
2912 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2913 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2914 Warning(IDLoc, "dividing zero by zero");
2916 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2918 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2922 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2926 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2931 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2932 Warning(IDLoc, "division by zero");
2935 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2939 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2944 // FIXME: The values for these two BranchTarget variables may be different in
2945 // micromips. These magic numbers need to be removed.
2946 unsigned BranchTargetNoTraps;
2947 unsigned BranchTarget;
2950 BranchTarget = IsMips64 ? 12 : 8;
2951 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2953 BranchTarget = IsMips64 ? 20 : 16;
2954 BranchTargetNoTraps = 8;
2955 // Branch to the li instruction.
2956 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2960 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2963 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2966 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2970 unsigned ATReg = getATReg(IDLoc);
2974 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2976 // Branch to the mflo instruction.
2977 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2978 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2979 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2981 // Branch to the mflo instruction.
2982 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2983 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2987 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2989 // Branch to the mflo instruction.
2990 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2991 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2992 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2994 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2998 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
2999 SmallVectorImpl<MCInst> &Instructions) {
3000 if (hasMips32r6() || hasMips64r6()) {
3001 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3005 warnIfNoMacro(IDLoc);
3007 const MCOperand &DstRegOp = Inst.getOperand(0);
3008 assert(DstRegOp.isReg() && "expected register operand kind");
3010 const MCOperand &SrcRegOp = Inst.getOperand(1);
3011 assert(SrcRegOp.isReg() && "expected register operand kind");
3013 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3014 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3016 unsigned DstReg = DstRegOp.getReg();
3017 unsigned SrcReg = SrcRegOp.getReg();
3018 int64_t OffsetValue = OffsetImmOp.getImm();
3020 // NOTE: We always need AT for ULHU, as it is always used as the source
3021 // register for one of the LBu's.
3022 unsigned ATReg = getATReg(IDLoc);
3026 // When the value of offset+1 does not fit in 16 bits, we have to load the
3027 // offset in AT, (D)ADDu the original source register (if there was one), and
3028 // then use AT as the source register for the 2 generated LBu's.
3029 bool LoadedOffsetInAT = false;
3030 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3031 LoadedOffsetInAT = true;
3033 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3034 true, IDLoc, Instructions))
3037 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3038 // because it will make our output more similar to GAS'. For example,
3039 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3040 // instead of just an "ori $1, $9, 32768".
3041 // NOTE: If there is no source register specified in the ULHU, the parser
3042 // will interpret it as $0.
3043 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3044 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3047 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3048 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3049 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3051 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3053 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3054 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3056 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3057 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3060 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3062 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3063 FirstLbuOffset, IDLoc, Instructions);
3065 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3068 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3070 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3075 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3076 SmallVectorImpl<MCInst> &Instructions) {
3077 if (hasMips32r6() || hasMips64r6()) {
3078 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3082 const MCOperand &DstRegOp = Inst.getOperand(0);
3083 assert(DstRegOp.isReg() && "expected register operand kind");
3085 const MCOperand &SrcRegOp = Inst.getOperand(1);
3086 assert(SrcRegOp.isReg() && "expected register operand kind");
3088 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3089 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3091 unsigned SrcReg = SrcRegOp.getReg();
3092 int64_t OffsetValue = OffsetImmOp.getImm();
3095 // When the value of offset+3 does not fit in 16 bits, we have to load the
3096 // offset in AT, (D)ADDu the original source register (if there was one), and
3097 // then use AT as the source register for the generated LWL and LWR.
3098 bool LoadedOffsetInAT = false;
3099 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3100 ATReg = getATReg(IDLoc);
3103 LoadedOffsetInAT = true;
3105 warnIfNoMacro(IDLoc);
3107 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3108 true, IDLoc, Instructions))
3111 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3112 // because it will make our output more similar to GAS'. For example,
3113 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3114 // instead of just an "ori $1, $9, 32768".
3115 // NOTE: If there is no source register specified in the ULW, the parser
3116 // will interpret it as $0.
3117 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3118 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3121 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3122 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3124 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3125 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3127 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3128 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3131 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3134 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3140 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3141 SmallVectorImpl<MCInst> &Instructions) {
3143 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3144 assert (Inst.getOperand(0).isReg() &&
3145 Inst.getOperand(1).isReg() &&
3146 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3148 unsigned ATReg = Mips::NoRegister;
3149 unsigned FinalDstReg = Mips::NoRegister;
3150 unsigned DstReg = Inst.getOperand(0).getReg();
3151 unsigned SrcReg = Inst.getOperand(1).getReg();
3152 int64_t ImmValue = Inst.getOperand(2).getImm();
3154 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3156 unsigned FinalOpcode = Inst.getOpcode();
3158 if (DstReg == SrcReg) {
3159 ATReg = getATReg(Inst.getLoc());
3162 FinalDstReg = DstReg;
3166 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3167 switch (FinalOpcode) {
3169 llvm_unreachable("unimplemented expansion");
3171 FinalOpcode = Mips::ADD;
3174 FinalOpcode = Mips::ADDu;
3177 FinalOpcode = Mips::AND;
3179 case (Mips::NORImm):
3180 FinalOpcode = Mips::NOR;
3183 FinalOpcode = Mips::OR;
3186 FinalOpcode = Mips::SLT;
3189 FinalOpcode = Mips::SLTu;
3192 FinalOpcode = Mips::XOR;
3196 if (FinalDstReg == Mips::NoRegister)
3197 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3199 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3206 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3207 SmallVectorImpl<MCInst> &Instructions) {
3208 if (hasShortDelaySlot)
3209 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3211 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3214 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3215 unsigned TrgReg, bool Is64Bit,
3216 SmallVectorImpl<MCInst> &Instructions) {
3217 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3221 void MipsAsmParser::createCpRestoreMemOp(
3222 bool IsLoad, int StackOffset, SMLoc IDLoc,
3223 SmallVectorImpl<MCInst> &Instructions) {
3224 // If the offset can not fit into 16 bits, we need to expand.
3225 if (!isInt<16>(StackOffset)) {
3227 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3228 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3229 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3230 MemInst.addOperand(MCOperand::createImm(StackOffset));
3231 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3235 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3239 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3240 // As described by the Mips32r2 spec, the registers Rd and Rs for
3241 // jalr.hb must be different.
3242 unsigned Opcode = Inst.getOpcode();
3244 if (Opcode == Mips::JALR_HB &&
3245 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3246 return Match_RequiresDifferentSrcAndDst;
3248 return Match_Success;
3251 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3252 uint64_t ErrorInfo) {
3253 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3254 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3255 if (ErrorLoc == SMLoc())
3262 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3263 OperandVector &Operands,
3265 uint64_t &ErrorInfo,
3266 bool MatchingInlineAsm) {
3269 SmallVector<MCInst, 8> Instructions;
3270 unsigned MatchResult =
3271 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3273 switch (MatchResult) {
3274 case Match_Success: {
3275 if (processInstruction(Inst, IDLoc, Instructions))
3277 for (unsigned i = 0; i < Instructions.size(); i++)
3278 Out.EmitInstruction(Instructions[i], STI);
3281 case Match_MissingFeature:
3282 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3284 case Match_InvalidOperand: {
3285 SMLoc ErrorLoc = IDLoc;
3286 if (ErrorInfo != ~0ULL) {
3287 if (ErrorInfo >= Operands.size())
3288 return Error(IDLoc, "too few operands for instruction");
3290 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3291 if (ErrorLoc == SMLoc())
3295 return Error(ErrorLoc, "invalid operand for instruction");
3297 case Match_MnemonicFail:
3298 return Error(IDLoc, "invalid instruction");
3299 case Match_RequiresDifferentSrcAndDst:
3300 return Error(IDLoc, "source and destination must be different");
3302 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3304 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3305 "expected 2-bit unsigned immediate");
3307 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3308 "expected immediate in range 1 .. 4");
3310 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3311 "expected 3-bit unsigned immediate");
3314 llvm_unreachable("Implement any new match types added!");
3317 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3318 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3319 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3320 ") without \".set noat\"");
3323 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3324 if (!AssemblerOptions.back()->isMacro())
3325 Warning(Loc, "macro instruction expanded into multiple instructions");
3329 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3330 SMRange Range, bool ShowColors) {
3331 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3332 Range, SMFixIt(Range, FixMsg),
3336 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3339 CC = StringSwitch<unsigned>(Name)
3375 if (!(isABI_N32() || isABI_N64()))
3378 if (12 <= CC && CC <= 15) {
3379 // Name is one of t4-t7
3380 AsmToken RegTok = getLexer().peekTok();
3381 SMRange RegRange = RegTok.getLocRange();
3383 StringRef FixedName = StringSwitch<StringRef>(Name)
3389 assert(FixedName != "" && "Register name is not one of t4-t7.");
3391 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3392 "Did you mean $" + FixedName + "?", RegRange);
3395 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3396 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3397 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3398 if (8 <= CC && CC <= 11)
3402 CC = StringSwitch<unsigned>(Name)
3414 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3417 CC = StringSwitch<unsigned>(Name)
3418 .Case("hwr_cpunum", 0)
3419 .Case("hwr_synci_step", 1)
3421 .Case("hwr_ccres", 3)
3422 .Case("hwr_ulr", 29)
3428 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3430 if (Name[0] == 'f') {
3431 StringRef NumString = Name.substr(1);
3433 if (NumString.getAsInteger(10, IntVal))
3434 return -1; // This is not an integer.
3435 if (IntVal > 31) // Maximum index for fpu register.
3442 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3444 if (Name.startswith("fcc")) {
3445 StringRef NumString = Name.substr(3);
3447 if (NumString.getAsInteger(10, IntVal))
3448 return -1; // This is not an integer.
3449 if (IntVal > 7) // There are only 8 fcc registers.
3456 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3458 if (Name.startswith("ac")) {
3459 StringRef NumString = Name.substr(2);
3461 if (NumString.getAsInteger(10, IntVal))
3462 return -1; // This is not an integer.
3463 if (IntVal > 3) // There are only 3 acc registers.
3470 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3473 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3482 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3485 CC = StringSwitch<unsigned>(Name)
3488 .Case("msaaccess", 2)
3490 .Case("msamodify", 4)
3491 .Case("msarequest", 5)
3493 .Case("msaunmap", 7)
3499 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3500 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3502 reportParseError(Loc,
3503 "pseudo-instruction requires $at, which is not available");
3506 unsigned AT = getReg(
3507 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3511 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3512 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3515 unsigned MipsAsmParser::getGPR(int RegNo) {
3516 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3520 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3522 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3525 return getReg(RegClass, RegNum);
3528 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3529 MCAsmParser &Parser = getParser();
3530 DEBUG(dbgs() << "parseOperand\n");
3532 // Check if the current operand has a custom associated parser, if so, try to
3533 // custom parse the operand, or fallback to the general approach.
3534 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3535 if (ResTy == MatchOperand_Success)
3537 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3538 // there was a match, but an error occurred, in which case, just return that
3539 // the operand parsing failed.
3540 if (ResTy == MatchOperand_ParseFail)
3543 DEBUG(dbgs() << ".. Generic Parser\n");
3545 switch (getLexer().getKind()) {
3547 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3549 case AsmToken::Dollar: {
3550 // Parse the register.
3551 SMLoc S = Parser.getTok().getLoc();
3553 // Almost all registers have been parsed by custom parsers. There is only
3554 // one exception to this. $zero (and it's alias $0) will reach this point
3555 // for div, divu, and similar instructions because it is not an operand
3556 // to the instruction definition but an explicit register. Special case
3557 // this situation for now.
3558 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3561 // Maybe it is a symbol reference.
3562 StringRef Identifier;
3563 if (Parser.parseIdentifier(Identifier))
3566 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3567 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3568 // Otherwise create a symbol reference.
3570 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3572 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3575 // Else drop to expression parsing.
3576 case AsmToken::LParen:
3577 case AsmToken::Minus:
3578 case AsmToken::Plus:
3579 case AsmToken::Integer:
3580 case AsmToken::Tilde:
3581 case AsmToken::String: {
3582 DEBUG(dbgs() << ".. generic integer\n");
3583 OperandMatchResultTy ResTy = parseImm(Operands);
3584 return ResTy != MatchOperand_Success;
3586 case AsmToken::Percent: {
3587 // It is a symbol reference or constant expression.
3588 const MCExpr *IdVal;
3589 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3590 if (parseRelocOperand(IdVal))
3593 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3595 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3597 } // case AsmToken::Percent
3598 } // switch(getLexer().getKind())
3602 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3603 StringRef RelocStr) {
3605 // Check the type of the expression.
3606 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3607 // It's a constant, evaluate reloc value.
3609 switch (getVariantKind(RelocStr)) {
3610 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3611 // Get the 1st 16-bits.
3612 Val = MCE->getValue() & 0xffff;
3614 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3615 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3616 // 16 bits being negative.
3617 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3619 case MCSymbolRefExpr::VK_Mips_HIGHER:
3620 // Get the 3rd 16-bits.
3621 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3623 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3624 // Get the 4th 16-bits.
3625 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3628 report_fatal_error("unsupported reloc value");
3630 return MCConstantExpr::create(Val, getContext());
3633 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3634 // It's a symbol, create a symbolic expression from the symbol.
3635 const MCSymbol *Symbol = &MSRE->getSymbol();
3636 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3637 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3641 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3642 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3644 // Try to create target expression.
3645 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3646 return MipsMCExpr::create(VK, Expr, getContext());
3648 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3649 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3650 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3654 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3655 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3656 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3659 // Just return the original expression.
3663 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3665 switch (Expr->getKind()) {
3666 case MCExpr::Constant:
3668 case MCExpr::SymbolRef:
3669 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3670 case MCExpr::Binary:
3671 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3672 if (!isEvaluated(BE->getLHS()))
3674 return isEvaluated(BE->getRHS());
3677 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3678 case MCExpr::Target:
3684 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3685 MCAsmParser &Parser = getParser();
3686 Parser.Lex(); // Eat the % token.
3687 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3688 if (Tok.isNot(AsmToken::Identifier))
3691 std::string Str = Tok.getIdentifier();
3693 Parser.Lex(); // Eat the identifier.
3694 // Now make an expression from the rest of the operand.
3695 const MCExpr *IdVal;
3698 if (getLexer().getKind() == AsmToken::LParen) {
3700 Parser.Lex(); // Eat the '(' token.
3701 if (getLexer().getKind() == AsmToken::Percent) {
3702 Parser.Lex(); // Eat the % token.
3703 const AsmToken &nextTok = Parser.getTok();
3704 if (nextTok.isNot(AsmToken::Identifier))
3707 Str += nextTok.getIdentifier();
3708 Parser.Lex(); // Eat the identifier.
3709 if (getLexer().getKind() != AsmToken::LParen)
3714 if (getParser().parseParenExpression(IdVal, EndLoc))
3717 while (getLexer().getKind() == AsmToken::RParen)
3718 Parser.Lex(); // Eat the ')' token.
3721 return true; // Parenthesis must follow the relocation operand.
3723 Res = evaluateRelocExpr(IdVal, Str);
3727 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3729 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3730 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3731 if (ResTy == MatchOperand_Success) {
3732 assert(Operands.size() == 1);
3733 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3734 StartLoc = Operand.getStartLoc();
3735 EndLoc = Operand.getEndLoc();
3737 // AFAIK, we only support numeric registers and named GPR's in CFI
3739 // Don't worry about eating tokens before failing. Using an unrecognised
3740 // register is a parse error.
3741 if (Operand.isGPRAsmReg()) {
3742 // Resolve to GPR32 or GPR64 appropriately.
3743 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3746 return (RegNo == (unsigned)-1);
3749 assert(Operands.size() == 0);
3750 return (RegNo == (unsigned)-1);
3753 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3754 MCAsmParser &Parser = getParser();
3757 unsigned NumOfLParen = 0;
3759 while (getLexer().getKind() == AsmToken::LParen) {
3764 switch (getLexer().getKind()) {
3767 case AsmToken::Identifier:
3768 case AsmToken::LParen:
3769 case AsmToken::Integer:
3770 case AsmToken::Minus:
3771 case AsmToken::Plus:
3773 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3775 Result = (getParser().parseExpression(Res));
3776 while (getLexer().getKind() == AsmToken::RParen)
3779 case AsmToken::Percent:
3780 Result = parseRelocOperand(Res);
3785 MipsAsmParser::OperandMatchResultTy
3786 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3787 MCAsmParser &Parser = getParser();
3788 DEBUG(dbgs() << "parseMemOperand\n");
3789 const MCExpr *IdVal = nullptr;
3791 bool isParenExpr = false;
3792 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3793 // First operand is the offset.
3794 S = Parser.getTok().getLoc();
3796 if (getLexer().getKind() == AsmToken::LParen) {
3801 if (getLexer().getKind() != AsmToken::Dollar) {
3802 if (parseMemOffset(IdVal, isParenExpr))
3803 return MatchOperand_ParseFail;
3805 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3806 if (Tok.isNot(AsmToken::LParen)) {
3807 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3808 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3810 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3811 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3812 return MatchOperand_Success;
3814 if (Tok.is(AsmToken::EndOfStatement)) {
3816 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3818 // Zero register assumed, add a memory operand with ZERO as its base.
3819 // "Base" will be managed by k_Memory.
3820 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3823 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3824 return MatchOperand_Success;
3826 Error(Parser.getTok().getLoc(), "'(' expected");
3827 return MatchOperand_ParseFail;
3830 Parser.Lex(); // Eat the '(' token.
3833 Res = parseAnyRegister(Operands);
3834 if (Res != MatchOperand_Success)
3837 if (Parser.getTok().isNot(AsmToken::RParen)) {
3838 Error(Parser.getTok().getLoc(), "')' expected");
3839 return MatchOperand_ParseFail;
3842 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3844 Parser.Lex(); // Eat the ')' token.
3847 IdVal = MCConstantExpr::create(0, getContext());
3849 // Replace the register operand with the memory operand.
3850 std::unique_ptr<MipsOperand> op(
3851 static_cast<MipsOperand *>(Operands.back().release()));
3852 // Remove the register from the operands.
3853 // "op" will be managed by k_Memory.
3854 Operands.pop_back();
3855 // Add the memory operand.
3856 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3858 if (IdVal->evaluateAsAbsolute(Imm))
3859 IdVal = MCConstantExpr::create(Imm, getContext());
3860 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3861 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3865 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3866 return MatchOperand_Success;
3869 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3870 MCAsmParser &Parser = getParser();
3871 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3873 SMLoc S = Parser.getTok().getLoc();
3875 if (Sym->isVariable())
3876 Expr = Sym->getVariableValue();
3879 if (Expr->getKind() == MCExpr::SymbolRef) {
3880 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3881 StringRef DefSymbol = Ref->getSymbol().getName();
3882 if (DefSymbol.startswith("$")) {
3883 OperandMatchResultTy ResTy =
3884 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3885 if (ResTy == MatchOperand_Success) {
3888 } else if (ResTy == MatchOperand_ParseFail)
3889 llvm_unreachable("Should never ParseFail");
3892 } else if (Expr->getKind() == MCExpr::Constant) {
3894 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3896 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3903 MipsAsmParser::OperandMatchResultTy
3904 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3905 StringRef Identifier,
3907 int Index = matchCPURegisterName(Identifier);
3909 Operands.push_back(MipsOperand::createGPRReg(
3910 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3911 return MatchOperand_Success;
3914 Index = matchHWRegsRegisterName(Identifier);
3916 Operands.push_back(MipsOperand::createHWRegsReg(
3917 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3918 return MatchOperand_Success;
3921 Index = matchFPURegisterName(Identifier);
3923 Operands.push_back(MipsOperand::createFGRReg(
3924 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3925 return MatchOperand_Success;
3928 Index = matchFCCRegisterName(Identifier);
3930 Operands.push_back(MipsOperand::createFCCReg(
3931 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3932 return MatchOperand_Success;
3935 Index = matchACRegisterName(Identifier);
3937 Operands.push_back(MipsOperand::createACCReg(
3938 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3939 return MatchOperand_Success;
3942 Index = matchMSA128RegisterName(Identifier);
3944 Operands.push_back(MipsOperand::createMSA128Reg(
3945 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3946 return MatchOperand_Success;
3949 Index = matchMSA128CtrlRegisterName(Identifier);
3951 Operands.push_back(MipsOperand::createMSACtrlReg(
3952 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3953 return MatchOperand_Success;
3956 return MatchOperand_NoMatch;
3959 MipsAsmParser::OperandMatchResultTy
3960 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3961 MCAsmParser &Parser = getParser();
3962 auto Token = Parser.getLexer().peekTok(false);
3964 if (Token.is(AsmToken::Identifier)) {
3965 DEBUG(dbgs() << ".. identifier\n");
3966 StringRef Identifier = Token.getIdentifier();
3967 OperandMatchResultTy ResTy =
3968 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3970 } else if (Token.is(AsmToken::Integer)) {
3971 DEBUG(dbgs() << ".. integer\n");
3972 Operands.push_back(MipsOperand::createNumericReg(
3973 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3975 return MatchOperand_Success;
3978 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3980 return MatchOperand_NoMatch;
3983 MipsAsmParser::OperandMatchResultTy
3984 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3985 MCAsmParser &Parser = getParser();
3986 DEBUG(dbgs() << "parseAnyRegister\n");
3988 auto Token = Parser.getTok();
3990 SMLoc S = Token.getLoc();
3992 if (Token.isNot(AsmToken::Dollar)) {
3993 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3994 if (Token.is(AsmToken::Identifier)) {
3995 if (searchSymbolAlias(Operands))
3996 return MatchOperand_Success;
3998 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3999 return MatchOperand_NoMatch;
4001 DEBUG(dbgs() << ".. $\n");
4003 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4004 if (ResTy == MatchOperand_Success) {
4006 Parser.Lex(); // identifier
4011 MipsAsmParser::OperandMatchResultTy
4012 MipsAsmParser::parseImm(OperandVector &Operands) {
4013 MCAsmParser &Parser = getParser();
4014 switch (getLexer().getKind()) {
4016 return MatchOperand_NoMatch;
4017 case AsmToken::LParen:
4018 case AsmToken::Minus:
4019 case AsmToken::Plus:
4020 case AsmToken::Integer:
4021 case AsmToken::Tilde:
4022 case AsmToken::String:
4026 const MCExpr *IdVal;
4027 SMLoc S = Parser.getTok().getLoc();
4028 if (getParser().parseExpression(IdVal))
4029 return MatchOperand_ParseFail;
4031 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4032 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4033 return MatchOperand_Success;
4036 MipsAsmParser::OperandMatchResultTy
4037 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4038 MCAsmParser &Parser = getParser();
4039 DEBUG(dbgs() << "parseJumpTarget\n");
4041 SMLoc S = getLexer().getLoc();
4043 // Integers and expressions are acceptable
4044 OperandMatchResultTy ResTy = parseImm(Operands);
4045 if (ResTy != MatchOperand_NoMatch)
4048 // Registers are a valid target and have priority over symbols.
4049 ResTy = parseAnyRegister(Operands);
4050 if (ResTy != MatchOperand_NoMatch)
4053 const MCExpr *Expr = nullptr;
4054 if (Parser.parseExpression(Expr)) {
4055 // We have no way of knowing if a symbol was consumed so we must ParseFail
4056 return MatchOperand_ParseFail;
4059 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4060 return MatchOperand_Success;
4063 MipsAsmParser::OperandMatchResultTy
4064 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4065 MCAsmParser &Parser = getParser();
4066 const MCExpr *IdVal;
4067 // If the first token is '$' we may have register operand.
4068 if (Parser.getTok().is(AsmToken::Dollar))
4069 return MatchOperand_NoMatch;
4070 SMLoc S = Parser.getTok().getLoc();
4071 if (getParser().parseExpression(IdVal))
4072 return MatchOperand_ParseFail;
4073 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4074 assert(MCE && "Unexpected MCExpr type.");
4075 int64_t Val = MCE->getValue();
4076 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4077 Operands.push_back(MipsOperand::CreateImm(
4078 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4079 return MatchOperand_Success;
4082 MipsAsmParser::OperandMatchResultTy
4083 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4084 MCAsmParser &Parser = getParser();
4085 switch (getLexer().getKind()) {
4087 return MatchOperand_NoMatch;
4088 case AsmToken::LParen:
4089 case AsmToken::Plus:
4090 case AsmToken::Minus:
4091 case AsmToken::Integer:
4096 SMLoc S = Parser.getTok().getLoc();
4098 if (getParser().parseExpression(Expr))
4099 return MatchOperand_ParseFail;
4102 if (!Expr->evaluateAsAbsolute(Val)) {
4103 Error(S, "expected immediate value");
4104 return MatchOperand_ParseFail;
4107 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4108 // and because the CPU always adds one to the immediate field, the allowed
4109 // range becomes 1..4. We'll only check the range here and will deal
4110 // with the addition/subtraction when actually decoding/encoding
4112 if (Val < 1 || Val > 4) {
4113 Error(S, "immediate not in range (1..4)");
4114 return MatchOperand_ParseFail;
4118 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4119 return MatchOperand_Success;
4122 MipsAsmParser::OperandMatchResultTy
4123 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4124 MCAsmParser &Parser = getParser();
4125 SmallVector<unsigned, 10> Regs;
4127 unsigned PrevReg = Mips::NoRegister;
4128 bool RegRange = false;
4129 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4131 if (Parser.getTok().isNot(AsmToken::Dollar))
4132 return MatchOperand_ParseFail;
4134 SMLoc S = Parser.getTok().getLoc();
4135 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4136 SMLoc E = getLexer().getLoc();
4137 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4138 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4140 // Remove last register operand because registers from register range
4141 // should be inserted first.
4142 if (RegNo == Mips::RA) {
4143 Regs.push_back(RegNo);
4145 unsigned TmpReg = PrevReg + 1;
4146 while (TmpReg <= RegNo) {
4147 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4148 Error(E, "invalid register operand");
4149 return MatchOperand_ParseFail;
4153 Regs.push_back(TmpReg++);
4159 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4160 (RegNo != Mips::RA)) {
4161 Error(E, "$16 or $31 expected");
4162 return MatchOperand_ParseFail;
4163 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4164 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4165 Error(E, "invalid register operand");
4166 return MatchOperand_ParseFail;
4167 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4168 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4169 Error(E, "consecutive register numbers expected");
4170 return MatchOperand_ParseFail;
4173 Regs.push_back(RegNo);
4176 if (Parser.getTok().is(AsmToken::Minus))
4179 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4180 !Parser.getTok().isNot(AsmToken::Comma)) {
4181 Error(E, "',' or '-' expected");
4182 return MatchOperand_ParseFail;
4185 Lex(); // Consume comma or minus
4186 if (Parser.getTok().isNot(AsmToken::Dollar))
4192 SMLoc E = Parser.getTok().getLoc();
4193 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4194 parseMemOperand(Operands);
4195 return MatchOperand_Success;
4198 MipsAsmParser::OperandMatchResultTy
4199 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4200 MCAsmParser &Parser = getParser();
4202 SMLoc S = Parser.getTok().getLoc();
4203 if (parseAnyRegister(Operands) != MatchOperand_Success)
4204 return MatchOperand_ParseFail;
4206 SMLoc E = Parser.getTok().getLoc();
4207 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4208 unsigned Reg = Op.getGPR32Reg();
4209 Operands.pop_back();
4210 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4211 return MatchOperand_Success;
4214 MipsAsmParser::OperandMatchResultTy
4215 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4216 MCAsmParser &Parser = getParser();
4217 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4218 SmallVector<unsigned, 10> Regs;
4220 if (Parser.getTok().isNot(AsmToken::Dollar))
4221 return MatchOperand_ParseFail;
4223 SMLoc S = Parser.getTok().getLoc();
4225 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4226 return MatchOperand_ParseFail;
4228 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4229 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4230 Regs.push_back(RegNo);
4232 SMLoc E = Parser.getTok().getLoc();
4233 if (Parser.getTok().isNot(AsmToken::Comma)) {
4234 Error(E, "',' expected");
4235 return MatchOperand_ParseFail;
4241 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4242 return MatchOperand_ParseFail;
4244 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4245 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4246 Regs.push_back(RegNo);
4248 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4250 return MatchOperand_Success;
4253 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4255 MCSymbolRefExpr::VariantKind VK =
4256 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4257 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4258 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4259 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4260 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4261 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4262 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4263 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4264 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4265 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4266 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4267 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4268 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4269 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4270 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4271 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4272 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4273 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4274 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4275 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4276 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4277 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4278 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4279 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4280 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4281 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4282 .Default(MCSymbolRefExpr::VK_None);
4284 assert(VK != MCSymbolRefExpr::VK_None);
4289 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4291 /// ::= '(', register, ')'
4292 /// handle it before we iterate so we don't get tripped up by the lack of
4294 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4295 MCAsmParser &Parser = getParser();
4296 if (getLexer().is(AsmToken::LParen)) {
4298 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4300 if (parseOperand(Operands, Name)) {
4301 SMLoc Loc = getLexer().getLoc();
4302 Parser.eatToEndOfStatement();
4303 return Error(Loc, "unexpected token in argument list");
4305 if (Parser.getTok().isNot(AsmToken::RParen)) {
4306 SMLoc Loc = getLexer().getLoc();
4307 Parser.eatToEndOfStatement();
4308 return Error(Loc, "unexpected token, expected ')'");
4311 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4317 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4318 /// either one of these.
4319 /// ::= '[', register, ']'
4320 /// ::= '[', integer, ']'
4321 /// handle it before we iterate so we don't get tripped up by the lack of
4323 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4324 OperandVector &Operands) {
4325 MCAsmParser &Parser = getParser();
4326 if (getLexer().is(AsmToken::LBrac)) {
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::RBrac)) {
4336 SMLoc Loc = getLexer().getLoc();
4337 Parser.eatToEndOfStatement();
4338 return Error(Loc, "unexpected token, expected ']'");
4341 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4347 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4348 SMLoc NameLoc, OperandVector &Operands) {
4349 MCAsmParser &Parser = getParser();
4350 DEBUG(dbgs() << "ParseInstruction\n");
4352 // We have reached first instruction, module directive are now forbidden.
4353 getTargetStreamer().forbidModuleDirective();
4355 // Check if we have valid mnemonic
4356 if (!mnemonicIsValid(Name, 0)) {
4357 Parser.eatToEndOfStatement();
4358 return Error(NameLoc, "unknown instruction");
4360 // First operand in MCInst is instruction mnemonic.
4361 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4363 // Read the remaining operands.
4364 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4365 // Read the first operand.
4366 if (parseOperand(Operands, Name)) {
4367 SMLoc Loc = getLexer().getLoc();
4368 Parser.eatToEndOfStatement();
4369 return Error(Loc, "unexpected token in argument list");
4371 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4373 // AFAIK, parenthesis suffixes are never on the first operand
4375 while (getLexer().is(AsmToken::Comma)) {
4376 Parser.Lex(); // Eat the comma.
4377 // Parse and remember the operand.
4378 if (parseOperand(Operands, Name)) {
4379 SMLoc Loc = getLexer().getLoc();
4380 Parser.eatToEndOfStatement();
4381 return Error(Loc, "unexpected token in argument list");
4383 // Parse bracket and parenthesis suffixes before we iterate
4384 if (getLexer().is(AsmToken::LBrac)) {
4385 if (parseBracketSuffix(Name, Operands))
4387 } else if (getLexer().is(AsmToken::LParen) &&
4388 parseParenSuffix(Name, Operands))
4392 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4393 SMLoc Loc = getLexer().getLoc();
4394 Parser.eatToEndOfStatement();
4395 return Error(Loc, "unexpected token in argument list");
4397 Parser.Lex(); // Consume the EndOfStatement.
4401 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4402 MCAsmParser &Parser = getParser();
4403 SMLoc Loc = getLexer().getLoc();
4404 Parser.eatToEndOfStatement();
4405 return Error(Loc, ErrorMsg);
4408 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4409 return Error(Loc, ErrorMsg);
4412 bool MipsAsmParser::parseSetNoAtDirective() {
4413 MCAsmParser &Parser = getParser();
4414 // Line should look like: ".set noat".
4416 // Set the $at register to $0.
4417 AssemblerOptions.back()->setATRegIndex(0);
4419 Parser.Lex(); // Eat "noat".
4421 // If this is not the end of the statement, report an error.
4422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4423 reportParseError("unexpected token, expected end of statement");
4427 getTargetStreamer().emitDirectiveSetNoAt();
4428 Parser.Lex(); // Consume the EndOfStatement.
4432 bool MipsAsmParser::parseSetAtDirective() {
4433 // Line can be: ".set at", which sets $at to $1
4434 // or ".set at=$reg", which sets $at to $reg.
4435 MCAsmParser &Parser = getParser();
4436 Parser.Lex(); // Eat "at".
4438 if (getLexer().is(AsmToken::EndOfStatement)) {
4439 // No register was specified, so we set $at to $1.
4440 AssemblerOptions.back()->setATRegIndex(1);
4442 getTargetStreamer().emitDirectiveSetAt();
4443 Parser.Lex(); // Consume the EndOfStatement.
4447 if (getLexer().isNot(AsmToken::Equal)) {
4448 reportParseError("unexpected token, expected equals sign");
4451 Parser.Lex(); // Eat "=".
4453 if (getLexer().isNot(AsmToken::Dollar)) {
4454 if (getLexer().is(AsmToken::EndOfStatement)) {
4455 reportParseError("no register specified");
4458 reportParseError("unexpected token, expected dollar sign '$'");
4462 Parser.Lex(); // Eat "$".
4464 // Find out what "reg" is.
4466 const AsmToken &Reg = Parser.getTok();
4467 if (Reg.is(AsmToken::Identifier)) {
4468 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4469 } else if (Reg.is(AsmToken::Integer)) {
4470 AtRegNo = Reg.getIntVal();
4472 reportParseError("unexpected token, expected identifier or integer");
4476 // Check if $reg is a valid register. If it is, set $at to $reg.
4477 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4478 reportParseError("invalid register");
4481 Parser.Lex(); // Eat "reg".
4483 // If this is not the end of the statement, report an error.
4484 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4485 reportParseError("unexpected token, expected end of statement");
4489 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4491 Parser.Lex(); // Consume the EndOfStatement.
4495 bool MipsAsmParser::parseSetReorderDirective() {
4496 MCAsmParser &Parser = getParser();
4498 // If this is not the end of the statement, report an error.
4499 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4500 reportParseError("unexpected token, expected end of statement");
4503 AssemblerOptions.back()->setReorder();
4504 getTargetStreamer().emitDirectiveSetReorder();
4505 Parser.Lex(); // Consume the EndOfStatement.
4509 bool MipsAsmParser::parseSetNoReorderDirective() {
4510 MCAsmParser &Parser = getParser();
4512 // If this is not the end of the statement, report an error.
4513 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4514 reportParseError("unexpected token, expected end of statement");
4517 AssemblerOptions.back()->setNoReorder();
4518 getTargetStreamer().emitDirectiveSetNoReorder();
4519 Parser.Lex(); // Consume the EndOfStatement.
4523 bool MipsAsmParser::parseSetMacroDirective() {
4524 MCAsmParser &Parser = getParser();
4526 // If this is not the end of the statement, report an error.
4527 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4528 reportParseError("unexpected token, expected end of statement");
4531 AssemblerOptions.back()->setMacro();
4532 getTargetStreamer().emitDirectiveSetMacro();
4533 Parser.Lex(); // Consume the EndOfStatement.
4537 bool MipsAsmParser::parseSetNoMacroDirective() {
4538 MCAsmParser &Parser = getParser();
4540 // If this is not the end of the statement, report an error.
4541 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4542 reportParseError("unexpected token, expected end of statement");
4545 if (AssemblerOptions.back()->isReorder()) {
4546 reportParseError("`noreorder' must be set before `nomacro'");
4549 AssemblerOptions.back()->setNoMacro();
4550 getTargetStreamer().emitDirectiveSetNoMacro();
4551 Parser.Lex(); // Consume the EndOfStatement.
4555 bool MipsAsmParser::parseSetMsaDirective() {
4556 MCAsmParser &Parser = getParser();
4559 // If this is not the end of the statement, report an error.
4560 if (getLexer().isNot(AsmToken::EndOfStatement))
4561 return reportParseError("unexpected token, expected end of statement");
4563 setFeatureBits(Mips::FeatureMSA, "msa");
4564 getTargetStreamer().emitDirectiveSetMsa();
4568 bool MipsAsmParser::parseSetNoMsaDirective() {
4569 MCAsmParser &Parser = getParser();
4572 // If this is not the end of the statement, report an error.
4573 if (getLexer().isNot(AsmToken::EndOfStatement))
4574 return reportParseError("unexpected token, expected end of statement");
4576 clearFeatureBits(Mips::FeatureMSA, "msa");
4577 getTargetStreamer().emitDirectiveSetNoMsa();
4581 bool MipsAsmParser::parseSetNoDspDirective() {
4582 MCAsmParser &Parser = getParser();
4583 Parser.Lex(); // Eat "nodsp".
4585 // If this is not the end of the statement, report an error.
4586 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4587 reportParseError("unexpected token, expected end of statement");
4591 clearFeatureBits(Mips::FeatureDSP, "dsp");
4592 getTargetStreamer().emitDirectiveSetNoDsp();
4596 bool MipsAsmParser::parseSetMips16Directive() {
4597 MCAsmParser &Parser = getParser();
4598 Parser.Lex(); // Eat "mips16".
4600 // If this is not the end of the statement, report an error.
4601 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4602 reportParseError("unexpected token, expected end of statement");
4606 setFeatureBits(Mips::FeatureMips16, "mips16");
4607 getTargetStreamer().emitDirectiveSetMips16();
4608 Parser.Lex(); // Consume the EndOfStatement.
4612 bool MipsAsmParser::parseSetNoMips16Directive() {
4613 MCAsmParser &Parser = getParser();
4614 Parser.Lex(); // Eat "nomips16".
4616 // If this is not the end of the statement, report an error.
4617 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4618 reportParseError("unexpected token, expected end of statement");
4622 clearFeatureBits(Mips::FeatureMips16, "mips16");
4623 getTargetStreamer().emitDirectiveSetNoMips16();
4624 Parser.Lex(); // Consume the EndOfStatement.
4628 bool MipsAsmParser::parseSetFpDirective() {
4629 MCAsmParser &Parser = getParser();
4630 MipsABIFlagsSection::FpABIKind FpAbiVal;
4631 // Line can be: .set fp=32
4634 Parser.Lex(); // Eat fp token
4635 AsmToken Tok = Parser.getTok();
4636 if (Tok.isNot(AsmToken::Equal)) {
4637 reportParseError("unexpected token, expected equals sign '='");
4640 Parser.Lex(); // Eat '=' token.
4641 Tok = Parser.getTok();
4643 if (!parseFpABIValue(FpAbiVal, ".set"))
4646 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4647 reportParseError("unexpected token, expected end of statement");
4650 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4651 Parser.Lex(); // Consume the EndOfStatement.
4655 bool MipsAsmParser::parseSetOddSPRegDirective() {
4656 MCAsmParser &Parser = getParser();
4658 Parser.Lex(); // Eat "oddspreg".
4659 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4660 reportParseError("unexpected token, expected end of statement");
4664 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4665 getTargetStreamer().emitDirectiveSetOddSPReg();
4669 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4670 MCAsmParser &Parser = getParser();
4672 Parser.Lex(); // Eat "nooddspreg".
4673 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4674 reportParseError("unexpected token, expected end of statement");
4678 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4679 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4683 bool MipsAsmParser::parseSetPopDirective() {
4684 MCAsmParser &Parser = getParser();
4685 SMLoc Loc = getLexer().getLoc();
4688 if (getLexer().isNot(AsmToken::EndOfStatement))
4689 return reportParseError("unexpected token, expected end of statement");
4691 // Always keep an element on the options "stack" to prevent the user
4692 // from changing the initial options. This is how we remember them.
4693 if (AssemblerOptions.size() == 2)
4694 return reportParseError(Loc, ".set pop with no .set push");
4696 AssemblerOptions.pop_back();
4697 setAvailableFeatures(
4698 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4699 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4701 getTargetStreamer().emitDirectiveSetPop();
4705 bool MipsAsmParser::parseSetPushDirective() {
4706 MCAsmParser &Parser = getParser();
4708 if (getLexer().isNot(AsmToken::EndOfStatement))
4709 return reportParseError("unexpected token, expected end of statement");
4711 // Create a copy of the current assembler options environment and push it.
4712 AssemblerOptions.push_back(
4713 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4715 getTargetStreamer().emitDirectiveSetPush();
4719 bool MipsAsmParser::parseSetSoftFloatDirective() {
4720 MCAsmParser &Parser = getParser();
4722 if (getLexer().isNot(AsmToken::EndOfStatement))
4723 return reportParseError("unexpected token, expected end of statement");
4725 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4726 getTargetStreamer().emitDirectiveSetSoftFloat();
4730 bool MipsAsmParser::parseSetHardFloatDirective() {
4731 MCAsmParser &Parser = getParser();
4733 if (getLexer().isNot(AsmToken::EndOfStatement))
4734 return reportParseError("unexpected token, expected end of statement");
4736 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4737 getTargetStreamer().emitDirectiveSetHardFloat();
4741 bool MipsAsmParser::parseSetAssignment() {
4743 const MCExpr *Value;
4744 MCAsmParser &Parser = getParser();
4746 if (Parser.parseIdentifier(Name))
4747 reportParseError("expected identifier after .set");
4749 if (getLexer().isNot(AsmToken::Comma))
4750 return reportParseError("unexpected token, expected comma");
4753 if (Parser.parseExpression(Value))
4754 return reportParseError("expected valid expression after comma");
4756 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4757 Sym->setVariableValue(Value);
4762 bool MipsAsmParser::parseSetMips0Directive() {
4763 MCAsmParser &Parser = getParser();
4765 if (getLexer().isNot(AsmToken::EndOfStatement))
4766 return reportParseError("unexpected token, expected end of statement");
4768 // Reset assembler options to their initial values.
4769 setAvailableFeatures(
4770 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4771 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4772 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4774 getTargetStreamer().emitDirectiveSetMips0();
4778 bool MipsAsmParser::parseSetArchDirective() {
4779 MCAsmParser &Parser = getParser();
4781 if (getLexer().isNot(AsmToken::Equal))
4782 return reportParseError("unexpected token, expected equals sign");
4786 if (Parser.parseIdentifier(Arch))
4787 return reportParseError("expected arch identifier");
4789 StringRef ArchFeatureName =
4790 StringSwitch<StringRef>(Arch)
4791 .Case("mips1", "mips1")
4792 .Case("mips2", "mips2")
4793 .Case("mips3", "mips3")
4794 .Case("mips4", "mips4")
4795 .Case("mips5", "mips5")
4796 .Case("mips32", "mips32")
4797 .Case("mips32r2", "mips32r2")
4798 .Case("mips32r3", "mips32r3")
4799 .Case("mips32r5", "mips32r5")
4800 .Case("mips32r6", "mips32r6")
4801 .Case("mips64", "mips64")
4802 .Case("mips64r2", "mips64r2")
4803 .Case("mips64r3", "mips64r3")
4804 .Case("mips64r5", "mips64r5")
4805 .Case("mips64r6", "mips64r6")
4806 .Case("cnmips", "cnmips")
4807 .Case("r4000", "mips3") // This is an implementation of Mips3.
4810 if (ArchFeatureName.empty())
4811 return reportParseError("unsupported architecture");
4813 selectArch(ArchFeatureName);
4814 getTargetStreamer().emitDirectiveSetArch(Arch);
4818 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4819 MCAsmParser &Parser = getParser();
4821 if (getLexer().isNot(AsmToken::EndOfStatement))
4822 return reportParseError("unexpected token, expected end of statement");
4826 llvm_unreachable("Unimplemented feature");
4827 case Mips::FeatureDSP:
4828 setFeatureBits(Mips::FeatureDSP, "dsp");
4829 getTargetStreamer().emitDirectiveSetDsp();
4831 case Mips::FeatureMicroMips:
4832 getTargetStreamer().emitDirectiveSetMicroMips();
4834 case Mips::FeatureMips1:
4835 selectArch("mips1");
4836 getTargetStreamer().emitDirectiveSetMips1();
4838 case Mips::FeatureMips2:
4839 selectArch("mips2");
4840 getTargetStreamer().emitDirectiveSetMips2();
4842 case Mips::FeatureMips3:
4843 selectArch("mips3");
4844 getTargetStreamer().emitDirectiveSetMips3();
4846 case Mips::FeatureMips4:
4847 selectArch("mips4");
4848 getTargetStreamer().emitDirectiveSetMips4();
4850 case Mips::FeatureMips5:
4851 selectArch("mips5");
4852 getTargetStreamer().emitDirectiveSetMips5();
4854 case Mips::FeatureMips32:
4855 selectArch("mips32");
4856 getTargetStreamer().emitDirectiveSetMips32();
4858 case Mips::FeatureMips32r2:
4859 selectArch("mips32r2");
4860 getTargetStreamer().emitDirectiveSetMips32R2();
4862 case Mips::FeatureMips32r3:
4863 selectArch("mips32r3");
4864 getTargetStreamer().emitDirectiveSetMips32R3();
4866 case Mips::FeatureMips32r5:
4867 selectArch("mips32r5");
4868 getTargetStreamer().emitDirectiveSetMips32R5();
4870 case Mips::FeatureMips32r6:
4871 selectArch("mips32r6");
4872 getTargetStreamer().emitDirectiveSetMips32R6();
4874 case Mips::FeatureMips64:
4875 selectArch("mips64");
4876 getTargetStreamer().emitDirectiveSetMips64();
4878 case Mips::FeatureMips64r2:
4879 selectArch("mips64r2");
4880 getTargetStreamer().emitDirectiveSetMips64R2();
4882 case Mips::FeatureMips64r3:
4883 selectArch("mips64r3");
4884 getTargetStreamer().emitDirectiveSetMips64R3();
4886 case Mips::FeatureMips64r5:
4887 selectArch("mips64r5");
4888 getTargetStreamer().emitDirectiveSetMips64R5();
4890 case Mips::FeatureMips64r6:
4891 selectArch("mips64r6");
4892 getTargetStreamer().emitDirectiveSetMips64R6();
4898 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4899 MCAsmParser &Parser = getParser();
4900 if (getLexer().isNot(AsmToken::Comma)) {
4901 SMLoc Loc = getLexer().getLoc();
4902 Parser.eatToEndOfStatement();
4903 return Error(Loc, ErrorStr);
4906 Parser.Lex(); // Eat the comma.
4910 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4911 // In this class, it is only used for .cprestore.
4912 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4913 // MipsTargetELFStreamer and MipsAsmParser.
4914 bool MipsAsmParser::isPicAndNotNxxAbi() {
4915 return inPicMode() && !(isABI_N32() || isABI_N64());
4918 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4919 if (AssemblerOptions.back()->isReorder())
4920 Warning(Loc, ".cpload should be inside a noreorder section");
4922 if (inMips16Mode()) {
4923 reportParseError(".cpload is not supported in Mips16 mode");
4927 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4928 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4929 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4930 reportParseError("expected register containing function address");
4934 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4935 if (!RegOpnd.isGPRAsmReg()) {
4936 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4940 // If this is not the end of the statement, report an error.
4941 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4942 reportParseError("unexpected token, expected end of statement");
4946 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4950 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4951 MCAsmParser &Parser = getParser();
4953 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4954 // is used in non-PIC mode.
4956 if (inMips16Mode()) {
4957 reportParseError(".cprestore is not supported in Mips16 mode");
4961 // Get the stack offset value.
4962 const MCExpr *StackOffset;
4963 int64_t StackOffsetVal;
4964 if (Parser.parseExpression(StackOffset)) {
4965 reportParseError("expected stack offset value");
4969 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4970 reportParseError("stack offset is not an absolute expression");
4974 if (StackOffsetVal < 0) {
4975 Warning(Loc, ".cprestore with negative stack offset has no effect");
4976 IsCpRestoreSet = false;
4978 IsCpRestoreSet = true;
4979 CpRestoreOffset = StackOffsetVal;
4982 // If this is not the end of the statement, report an error.
4983 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4984 reportParseError("unexpected token, expected end of statement");
4988 // Store the $gp on the stack.
4989 SmallVector<MCInst, 3> StoreInsts;
4990 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
4993 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
4994 Parser.Lex(); // Consume the EndOfStatement.
4998 bool MipsAsmParser::parseDirectiveCPSetup() {
4999 MCAsmParser &Parser = getParser();
5002 bool SaveIsReg = true;
5004 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5005 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5006 if (ResTy == MatchOperand_NoMatch) {
5007 reportParseError("expected register containing function address");
5008 Parser.eatToEndOfStatement();
5012 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5013 if (!FuncRegOpnd.isGPRAsmReg()) {
5014 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5015 Parser.eatToEndOfStatement();
5019 FuncReg = FuncRegOpnd.getGPR32Reg();
5022 if (!eatComma("unexpected token, expected comma"))
5025 ResTy = parseAnyRegister(TmpReg);
5026 if (ResTy == MatchOperand_NoMatch) {
5027 const MCExpr *OffsetExpr;
5029 SMLoc ExprLoc = getLexer().getLoc();
5031 if (Parser.parseExpression(OffsetExpr) ||
5032 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5033 reportParseError(ExprLoc, "expected save register or stack offset");
5034 Parser.eatToEndOfStatement();
5041 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5042 if (!SaveOpnd.isGPRAsmReg()) {
5043 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5044 Parser.eatToEndOfStatement();
5047 Save = SaveOpnd.getGPR32Reg();
5050 if (!eatComma("unexpected token, expected comma"))
5054 if (Parser.parseExpression(Expr)) {
5055 reportParseError("expected expression");
5059 if (Expr->getKind() != MCExpr::SymbolRef) {
5060 reportParseError("expected symbol");
5063 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5065 CpSaveLocation = Save;
5066 CpSaveLocationIsRegister = SaveIsReg;
5068 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5073 bool MipsAsmParser::parseDirectiveCPReturn() {
5074 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5075 CpSaveLocationIsRegister);
5079 bool MipsAsmParser::parseDirectiveNaN() {
5080 MCAsmParser &Parser = getParser();
5081 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5082 const AsmToken &Tok = Parser.getTok();
5084 if (Tok.getString() == "2008") {
5086 getTargetStreamer().emitDirectiveNaN2008();
5088 } else if (Tok.getString() == "legacy") {
5090 getTargetStreamer().emitDirectiveNaNLegacy();
5094 // If we don't recognize the option passed to the .nan
5095 // directive (e.g. no option or unknown option), emit an error.
5096 reportParseError("invalid option in .nan directive");
5100 bool MipsAsmParser::parseDirectiveSet() {
5101 MCAsmParser &Parser = getParser();
5102 // Get the next token.
5103 const AsmToken &Tok = Parser.getTok();
5105 if (Tok.getString() == "noat") {
5106 return parseSetNoAtDirective();
5107 } else if (Tok.getString() == "at") {
5108 return parseSetAtDirective();
5109 } else if (Tok.getString() == "arch") {
5110 return parseSetArchDirective();
5111 } else if (Tok.getString() == "fp") {
5112 return parseSetFpDirective();
5113 } else if (Tok.getString() == "oddspreg") {
5114 return parseSetOddSPRegDirective();
5115 } else if (Tok.getString() == "nooddspreg") {
5116 return parseSetNoOddSPRegDirective();
5117 } else if (Tok.getString() == "pop") {
5118 return parseSetPopDirective();
5119 } else if (Tok.getString() == "push") {
5120 return parseSetPushDirective();
5121 } else if (Tok.getString() == "reorder") {
5122 return parseSetReorderDirective();
5123 } else if (Tok.getString() == "noreorder") {
5124 return parseSetNoReorderDirective();
5125 } else if (Tok.getString() == "macro") {
5126 return parseSetMacroDirective();
5127 } else if (Tok.getString() == "nomacro") {
5128 return parseSetNoMacroDirective();
5129 } else if (Tok.getString() == "mips16") {
5130 return parseSetMips16Directive();
5131 } else if (Tok.getString() == "nomips16") {
5132 return parseSetNoMips16Directive();
5133 } else if (Tok.getString() == "nomicromips") {
5134 getTargetStreamer().emitDirectiveSetNoMicroMips();
5135 Parser.eatToEndOfStatement();
5137 } else if (Tok.getString() == "micromips") {
5138 return parseSetFeature(Mips::FeatureMicroMips);
5139 } else if (Tok.getString() == "mips0") {
5140 return parseSetMips0Directive();
5141 } else if (Tok.getString() == "mips1") {
5142 return parseSetFeature(Mips::FeatureMips1);
5143 } else if (Tok.getString() == "mips2") {
5144 return parseSetFeature(Mips::FeatureMips2);
5145 } else if (Tok.getString() == "mips3") {
5146 return parseSetFeature(Mips::FeatureMips3);
5147 } else if (Tok.getString() == "mips4") {
5148 return parseSetFeature(Mips::FeatureMips4);
5149 } else if (Tok.getString() == "mips5") {
5150 return parseSetFeature(Mips::FeatureMips5);
5151 } else if (Tok.getString() == "mips32") {
5152 return parseSetFeature(Mips::FeatureMips32);
5153 } else if (Tok.getString() == "mips32r2") {
5154 return parseSetFeature(Mips::FeatureMips32r2);
5155 } else if (Tok.getString() == "mips32r3") {
5156 return parseSetFeature(Mips::FeatureMips32r3);
5157 } else if (Tok.getString() == "mips32r5") {
5158 return parseSetFeature(Mips::FeatureMips32r5);
5159 } else if (Tok.getString() == "mips32r6") {
5160 return parseSetFeature(Mips::FeatureMips32r6);
5161 } else if (Tok.getString() == "mips64") {
5162 return parseSetFeature(Mips::FeatureMips64);
5163 } else if (Tok.getString() == "mips64r2") {
5164 return parseSetFeature(Mips::FeatureMips64r2);
5165 } else if (Tok.getString() == "mips64r3") {
5166 return parseSetFeature(Mips::FeatureMips64r3);
5167 } else if (Tok.getString() == "mips64r5") {
5168 return parseSetFeature(Mips::FeatureMips64r5);
5169 } else if (Tok.getString() == "mips64r6") {
5170 return parseSetFeature(Mips::FeatureMips64r6);
5171 } else if (Tok.getString() == "dsp") {
5172 return parseSetFeature(Mips::FeatureDSP);
5173 } else if (Tok.getString() == "nodsp") {
5174 return parseSetNoDspDirective();
5175 } else if (Tok.getString() == "msa") {
5176 return parseSetMsaDirective();
5177 } else if (Tok.getString() == "nomsa") {
5178 return parseSetNoMsaDirective();
5179 } else if (Tok.getString() == "softfloat") {
5180 return parseSetSoftFloatDirective();
5181 } else if (Tok.getString() == "hardfloat") {
5182 return parseSetHardFloatDirective();
5184 // It is just an identifier, look for an assignment.
5185 parseSetAssignment();
5192 /// parseDataDirective
5193 /// ::= .word [ expression (, expression)* ]
5194 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5195 MCAsmParser &Parser = getParser();
5196 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5198 const MCExpr *Value;
5199 if (getParser().parseExpression(Value))
5202 getParser().getStreamer().EmitValue(Value, Size);
5204 if (getLexer().is(AsmToken::EndOfStatement))
5207 if (getLexer().isNot(AsmToken::Comma))
5208 return Error(L, "unexpected token, expected comma");
5217 /// parseDirectiveGpWord
5218 /// ::= .gpword local_sym
5219 bool MipsAsmParser::parseDirectiveGpWord() {
5220 MCAsmParser &Parser = getParser();
5221 const MCExpr *Value;
5222 // EmitGPRel32Value requires an expression, so we are using base class
5223 // method to evaluate the expression.
5224 if (getParser().parseExpression(Value))
5226 getParser().getStreamer().EmitGPRel32Value(Value);
5228 if (getLexer().isNot(AsmToken::EndOfStatement))
5229 return Error(getLexer().getLoc(),
5230 "unexpected token, expected end of statement");
5231 Parser.Lex(); // Eat EndOfStatement token.
5235 /// parseDirectiveGpDWord
5236 /// ::= .gpdword local_sym
5237 bool MipsAsmParser::parseDirectiveGpDWord() {
5238 MCAsmParser &Parser = getParser();
5239 const MCExpr *Value;
5240 // EmitGPRel64Value requires an expression, so we are using base class
5241 // method to evaluate the expression.
5242 if (getParser().parseExpression(Value))
5244 getParser().getStreamer().EmitGPRel64Value(Value);
5246 if (getLexer().isNot(AsmToken::EndOfStatement))
5247 return Error(getLexer().getLoc(),
5248 "unexpected token, expected end of statement");
5249 Parser.Lex(); // Eat EndOfStatement token.
5253 bool MipsAsmParser::parseDirectiveOption() {
5254 MCAsmParser &Parser = getParser();
5255 // Get the option token.
5256 AsmToken Tok = Parser.getTok();
5257 // At the moment only identifiers are supported.
5258 if (Tok.isNot(AsmToken::Identifier)) {
5259 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5260 Parser.eatToEndOfStatement();
5264 StringRef Option = Tok.getIdentifier();
5266 if (Option == "pic0") {
5267 // MipsAsmParser needs to know if the current PIC mode changes.
5268 IsPicEnabled = false;
5270 getTargetStreamer().emitDirectiveOptionPic0();
5272 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5273 Error(Parser.getTok().getLoc(),
5274 "unexpected token, expected end of statement");
5275 Parser.eatToEndOfStatement();
5280 if (Option == "pic2") {
5281 // MipsAsmParser needs to know if the current PIC mode changes.
5282 IsPicEnabled = true;
5284 getTargetStreamer().emitDirectiveOptionPic2();
5286 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5287 Error(Parser.getTok().getLoc(),
5288 "unexpected token, expected end of statement");
5289 Parser.eatToEndOfStatement();
5295 Warning(Parser.getTok().getLoc(),
5296 "unknown option, expected 'pic0' or 'pic2'");
5297 Parser.eatToEndOfStatement();
5301 /// parseInsnDirective
5303 bool MipsAsmParser::parseInsnDirective() {
5304 // If this is not the end of the statement, report an error.
5305 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5306 reportParseError("unexpected token, expected end of statement");
5310 // The actual label marking happens in
5311 // MipsELFStreamer::createPendingLabelRelocs().
5312 getTargetStreamer().emitDirectiveInsn();
5314 getParser().Lex(); // Eat EndOfStatement token.
5318 /// parseDirectiveModule
5319 /// ::= .module oddspreg
5320 /// ::= .module nooddspreg
5321 /// ::= .module fp=value
5322 /// ::= .module softfloat
5323 /// ::= .module hardfloat
5324 bool MipsAsmParser::parseDirectiveModule() {
5325 MCAsmParser &Parser = getParser();
5326 MCAsmLexer &Lexer = getLexer();
5327 SMLoc L = Lexer.getLoc();
5329 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5330 // TODO : get a better message.
5331 reportParseError(".module directive must appear before any code");
5336 if (Parser.parseIdentifier(Option)) {
5337 reportParseError("expected .module option identifier");
5341 if (Option == "oddspreg") {
5342 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5344 // Synchronize the abiflags information with the FeatureBits information we
5346 getTargetStreamer().updateABIInfo(*this);
5348 // If printing assembly, use the recently updated abiflags information.
5349 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5350 // emitted at the end).
5351 getTargetStreamer().emitDirectiveModuleOddSPReg();
5353 // If this is not the end of the statement, report an error.
5354 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5355 reportParseError("unexpected token, expected end of statement");
5359 return false; // parseDirectiveModule has finished successfully.
5360 } else if (Option == "nooddspreg") {
5362 Error(L, "'.module nooddspreg' requires the O32 ABI");
5366 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5368 // Synchronize the abiflags information with the FeatureBits information we
5370 getTargetStreamer().updateABIInfo(*this);
5372 // If printing assembly, use the recently updated abiflags information.
5373 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5374 // emitted at the end).
5375 getTargetStreamer().emitDirectiveModuleOddSPReg();
5377 // If this is not the end of the statement, report an error.
5378 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5379 reportParseError("unexpected token, expected end of statement");
5383 return false; // parseDirectiveModule has finished successfully.
5384 } else if (Option == "fp") {
5385 return parseDirectiveModuleFP();
5386 } else if (Option == "softfloat") {
5387 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5389 // Synchronize the ABI Flags information with the FeatureBits information we
5391 getTargetStreamer().updateABIInfo(*this);
5393 // If printing assembly, use the recently updated ABI Flags information.
5394 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5396 getTargetStreamer().emitDirectiveModuleSoftFloat();
5398 // If this is not the end of the statement, report an error.
5399 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5400 reportParseError("unexpected token, expected end of statement");
5404 return false; // parseDirectiveModule has finished successfully.
5405 } else if (Option == "hardfloat") {
5406 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5408 // Synchronize the ABI Flags information with the FeatureBits information we
5410 getTargetStreamer().updateABIInfo(*this);
5412 // If printing assembly, use the recently updated ABI Flags information.
5413 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5415 getTargetStreamer().emitDirectiveModuleHardFloat();
5417 // If this is not the end of the statement, report an error.
5418 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5419 reportParseError("unexpected token, expected end of statement");
5423 return false; // parseDirectiveModule has finished successfully.
5425 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5429 /// parseDirectiveModuleFP
5433 bool MipsAsmParser::parseDirectiveModuleFP() {
5434 MCAsmParser &Parser = getParser();
5435 MCAsmLexer &Lexer = getLexer();
5437 if (Lexer.isNot(AsmToken::Equal)) {
5438 reportParseError("unexpected token, expected equals sign '='");
5441 Parser.Lex(); // Eat '=' token.
5443 MipsABIFlagsSection::FpABIKind FpABI;
5444 if (!parseFpABIValue(FpABI, ".module"))
5447 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5448 reportParseError("unexpected token, expected end of statement");
5452 // Synchronize the abiflags information with the FeatureBits information we
5454 getTargetStreamer().updateABIInfo(*this);
5456 // If printing assembly, use the recently updated abiflags information.
5457 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5458 // emitted at the end).
5459 getTargetStreamer().emitDirectiveModuleFP();
5461 Parser.Lex(); // Consume the EndOfStatement.
5465 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5466 StringRef Directive) {
5467 MCAsmParser &Parser = getParser();
5468 MCAsmLexer &Lexer = getLexer();
5469 bool ModuleLevelOptions = Directive == ".module";
5471 if (Lexer.is(AsmToken::Identifier)) {
5472 StringRef Value = Parser.getTok().getString();
5475 if (Value != "xx") {
5476 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5481 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5485 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5486 if (ModuleLevelOptions) {
5487 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5488 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5490 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5491 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5496 if (Lexer.is(AsmToken::Integer)) {
5497 unsigned Value = Parser.getTok().getIntVal();
5500 if (Value != 32 && Value != 64) {
5501 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5507 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5511 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5512 if (ModuleLevelOptions) {
5513 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5514 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5516 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5517 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5520 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5521 if (ModuleLevelOptions) {
5522 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5523 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5525 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5526 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5536 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5537 MCAsmParser &Parser = getParser();
5538 StringRef IDVal = DirectiveID.getString();
5540 if (IDVal == ".cpload")
5541 return parseDirectiveCpLoad(DirectiveID.getLoc());
5542 if (IDVal == ".cprestore")
5543 return parseDirectiveCpRestore(DirectiveID.getLoc());
5544 if (IDVal == ".dword") {
5545 parseDataDirective(8, DirectiveID.getLoc());
5548 if (IDVal == ".ent") {
5549 StringRef SymbolName;
5551 if (Parser.parseIdentifier(SymbolName)) {
5552 reportParseError("expected identifier after .ent");
5556 // There's an undocumented extension that allows an integer to
5557 // follow the name of the procedure which AFAICS is ignored by GAS.
5558 // Example: .ent foo,2
5559 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5560 if (getLexer().isNot(AsmToken::Comma)) {
5561 // Even though we accept this undocumented extension for compatibility
5562 // reasons, the additional integer argument does not actually change
5563 // the behaviour of the '.ent' directive, so we would like to discourage
5564 // its use. We do this by not referring to the extended version in
5565 // error messages which are not directly related to its use.
5566 reportParseError("unexpected token, expected end of statement");
5569 Parser.Lex(); // Eat the comma.
5570 const MCExpr *DummyNumber;
5571 int64_t DummyNumberVal;
5572 // If the user was explicitly trying to use the extended version,
5573 // we still give helpful extension-related error messages.
5574 if (Parser.parseExpression(DummyNumber)) {
5575 reportParseError("expected number after comma");
5578 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5579 reportParseError("expected an absolute expression after comma");
5584 // If this is not the end of the statement, report an error.
5585 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5586 reportParseError("unexpected token, expected end of statement");
5590 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5592 getTargetStreamer().emitDirectiveEnt(*Sym);
5594 IsCpRestoreSet = false;
5598 if (IDVal == ".end") {
5599 StringRef SymbolName;
5601 if (Parser.parseIdentifier(SymbolName)) {
5602 reportParseError("expected identifier after .end");
5606 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5607 reportParseError("unexpected token, expected end of statement");
5611 if (CurrentFn == nullptr) {
5612 reportParseError(".end used without .ent");
5616 if ((SymbolName != CurrentFn->getName())) {
5617 reportParseError(".end symbol does not match .ent symbol");
5621 getTargetStreamer().emitDirectiveEnd(SymbolName);
5622 CurrentFn = nullptr;
5623 IsCpRestoreSet = false;
5627 if (IDVal == ".frame") {
5628 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5629 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5630 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5631 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5632 reportParseError("expected stack register");
5636 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5637 if (!StackRegOpnd.isGPRAsmReg()) {
5638 reportParseError(StackRegOpnd.getStartLoc(),
5639 "expected general purpose register");
5642 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5644 if (Parser.getTok().is(AsmToken::Comma))
5647 reportParseError("unexpected token, expected comma");
5651 // Parse the frame size.
5652 const MCExpr *FrameSize;
5653 int64_t FrameSizeVal;
5655 if (Parser.parseExpression(FrameSize)) {
5656 reportParseError("expected frame size value");
5660 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5661 reportParseError("frame size not an absolute expression");
5665 if (Parser.getTok().is(AsmToken::Comma))
5668 reportParseError("unexpected token, expected comma");
5672 // Parse the return register.
5674 ResTy = parseAnyRegister(TmpReg);
5675 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5676 reportParseError("expected return register");
5680 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5681 if (!ReturnRegOpnd.isGPRAsmReg()) {
5682 reportParseError(ReturnRegOpnd.getStartLoc(),
5683 "expected general purpose register");
5687 // If this is not the end of the statement, report an error.
5688 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5689 reportParseError("unexpected token, expected end of statement");
5693 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5694 ReturnRegOpnd.getGPR32Reg());
5695 IsCpRestoreSet = false;
5699 if (IDVal == ".set") {
5700 return parseDirectiveSet();
5703 if (IDVal == ".mask" || IDVal == ".fmask") {
5704 // .mask bitmask, frame_offset
5705 // bitmask: One bit for each register used.
5706 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5707 // first register is expected to be saved.
5709 // .mask 0x80000000, -4
5710 // .fmask 0x80000000, -4
5713 // Parse the bitmask
5714 const MCExpr *BitMask;
5717 if (Parser.parseExpression(BitMask)) {
5718 reportParseError("expected bitmask value");
5722 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5723 reportParseError("bitmask not an absolute expression");
5727 if (Parser.getTok().is(AsmToken::Comma))
5730 reportParseError("unexpected token, expected comma");
5734 // Parse the frame_offset
5735 const MCExpr *FrameOffset;
5736 int64_t FrameOffsetVal;
5738 if (Parser.parseExpression(FrameOffset)) {
5739 reportParseError("expected frame offset value");
5743 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5744 reportParseError("frame offset not an absolute expression");
5748 // If this is not the end of the statement, report an error.
5749 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5750 reportParseError("unexpected token, expected end of statement");
5754 if (IDVal == ".mask")
5755 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5757 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5761 if (IDVal == ".nan")
5762 return parseDirectiveNaN();
5764 if (IDVal == ".gpword") {
5765 parseDirectiveGpWord();
5769 if (IDVal == ".gpdword") {
5770 parseDirectiveGpDWord();
5774 if (IDVal == ".word") {
5775 parseDataDirective(4, DirectiveID.getLoc());
5779 if (IDVal == ".option")
5780 return parseDirectiveOption();
5782 if (IDVal == ".abicalls") {
5783 getTargetStreamer().emitDirectiveAbiCalls();
5784 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5785 Error(Parser.getTok().getLoc(),
5786 "unexpected token, expected end of statement");
5788 Parser.eatToEndOfStatement();
5793 if (IDVal == ".cpsetup")
5794 return parseDirectiveCPSetup();
5796 if (IDVal == ".cpreturn")
5797 return parseDirectiveCPReturn();
5799 if (IDVal == ".module")
5800 return parseDirectiveModule();
5802 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5803 return parseInternalDirectiveReallowModule();
5805 if (IDVal == ".insn")
5806 return parseInsnDirective();
5811 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5812 // If this is not the end of the statement, report an error.
5813 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5814 reportParseError("unexpected token, expected end of statement");
5818 getTargetStreamer().reallowModuleDirective();
5820 getParser().Lex(); // Eat EndOfStatement token.
5824 extern "C" void LLVMInitializeMipsAsmParser() {
5825 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5826 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5827 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5828 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5831 #define GET_REGISTER_MATCHER
5832 #define GET_MATCHER_IMPLEMENTATION
5833 #include "MipsGenAsmMatcher.inc"