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 bool needsExpansion(MCInst &Inst);
172 // Expands assembly pseudo instructions.
173 // Returns false on success, true otherwise.
174 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
175 SmallVectorImpl<MCInst> &Instructions);
177 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
178 SmallVectorImpl<MCInst> &Instructions);
180 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
181 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
182 SmallVectorImpl<MCInst> &Instructions);
184 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
185 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
191 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
192 const MCOperand &Offset, bool Is32BitAddress,
193 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
195 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions);
198 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
199 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
202 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions);
205 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions);
208 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
215 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
218 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions);
221 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
222 SmallVectorImpl<MCInst> &Instructions);
224 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
225 SmallVectorImpl<MCInst> &Instructions);
227 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
228 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
230 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
231 SmallVectorImpl<MCInst> &Instructions);
233 bool reportParseError(Twine ErrorMsg);
234 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
236 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
237 bool parseRelocOperand(const MCExpr *&Res);
239 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
241 bool isEvaluated(const MCExpr *Expr);
242 bool parseSetMips0Directive();
243 bool parseSetArchDirective();
244 bool parseSetFeature(uint64_t Feature);
245 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
246 bool parseDirectiveCpLoad(SMLoc Loc);
247 bool parseDirectiveCpRestore(SMLoc Loc);
248 bool parseDirectiveCPSetup();
249 bool parseDirectiveCPReturn();
250 bool parseDirectiveNaN();
251 bool parseDirectiveSet();
252 bool parseDirectiveOption();
253 bool parseInsnDirective();
255 bool parseSetAtDirective();
256 bool parseSetNoAtDirective();
257 bool parseSetMacroDirective();
258 bool parseSetNoMacroDirective();
259 bool parseSetMsaDirective();
260 bool parseSetNoMsaDirective();
261 bool parseSetNoDspDirective();
262 bool parseSetReorderDirective();
263 bool parseSetNoReorderDirective();
264 bool parseSetMips16Directive();
265 bool parseSetNoMips16Directive();
266 bool parseSetFpDirective();
267 bool parseSetOddSPRegDirective();
268 bool parseSetNoOddSPRegDirective();
269 bool parseSetPopDirective();
270 bool parseSetPushDirective();
271 bool parseSetSoftFloatDirective();
272 bool parseSetHardFloatDirective();
274 bool parseSetAssignment();
276 bool parseDataDirective(unsigned Size, SMLoc L);
277 bool parseDirectiveGpWord();
278 bool parseDirectiveGpDWord();
279 bool parseDirectiveModule();
280 bool parseDirectiveModuleFP();
281 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
282 StringRef Directive);
284 bool parseInternalDirectiveReallowModule();
286 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
288 bool eatComma(StringRef ErrorStr);
290 int matchCPURegisterName(StringRef Symbol);
292 int matchHWRegsRegisterName(StringRef Symbol);
294 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
296 int matchFPURegisterName(StringRef Name);
298 int matchFCCRegisterName(StringRef Name);
300 int matchACRegisterName(StringRef Name);
302 int matchMSA128RegisterName(StringRef Name);
304 int matchMSA128CtrlRegisterName(StringRef Name);
306 unsigned getReg(int RC, int RegNo);
308 unsigned getGPR(int RegNo);
310 /// Returns the internal register number for the current AT. Also checks if
311 /// the current AT is unavailable (set to $0) and gives an error if it is.
312 /// This should be used in pseudo-instruction expansions which need AT.
313 unsigned getATReg(SMLoc Loc);
315 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
316 SmallVectorImpl<MCInst> &Instructions);
318 // Helper function that checks if the value of a vector index is within the
319 // boundaries of accepted values for each RegisterKind
320 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
321 bool validateMSAIndex(int Val, int RegKind);
323 // Selects a new architecture by updating the FeatureBits with the necessary
324 // info including implied dependencies.
325 // Internally, it clears all the feature bits related to *any* architecture
326 // and selects the new one using the ToggleFeature functionality of the
327 // MCSubtargetInfo object that handles implied dependencies. The reason we
328 // clear all the arch related bits manually is because ToggleFeature only
329 // clears the features that imply the feature being cleared and not the
330 // features implied by the feature being cleared. This is easier to see
332 // --------------------------------------------------
333 // | Feature | Implies |
334 // | -------------------------------------------------|
335 // | FeatureMips1 | None |
336 // | FeatureMips2 | FeatureMips1 |
337 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
338 // | FeatureMips4 | FeatureMips3 |
340 // --------------------------------------------------
342 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
343 // FeatureMipsGP64 | FeatureMips1)
344 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
345 void selectArch(StringRef ArchFeature) {
346 FeatureBitset FeatureBits = STI.getFeatureBits();
347 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
348 STI.setFeatureBits(FeatureBits);
349 setAvailableFeatures(
350 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
351 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
354 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
355 if (!(STI.getFeatureBits()[Feature])) {
356 setAvailableFeatures(
357 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
358 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
362 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
363 if (STI.getFeatureBits()[Feature]) {
364 setAvailableFeatures(
365 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
366 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
370 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
371 setFeatureBits(Feature, FeatureString);
372 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
375 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
376 clearFeatureBits(Feature, FeatureString);
377 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
381 enum MipsMatchResultTy {
382 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
383 #define GET_OPERAND_DIAGNOSTIC_TYPES
384 #include "MipsGenAsmMatcher.inc"
385 #undef GET_OPERAND_DIAGNOSTIC_TYPES
389 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
390 const MCInstrInfo &MII, const MCTargetOptions &Options)
391 : MCTargetAsmParser(Options), STI(sti),
392 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
393 sti.getCPU(), Options)) {
394 MCAsmParserExtension::Initialize(parser);
396 parser.addAliasForDirective(".asciiz", ".asciz");
398 // Initialize the set of available features.
399 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
401 // Remember the initial assembler options. The user can not modify these.
402 AssemblerOptions.push_back(
403 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
405 // Create an assembler options environment for the user to modify.
406 AssemblerOptions.push_back(
407 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
409 getTargetStreamer().updateABIInfo(*this);
411 if (!isABI_O32() && !useOddSPReg() != 0)
412 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
417 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
419 IsCpRestoreSet = false;
420 CpRestoreOffset = -1;
422 Triple TheTriple(sti.getTargetTriple());
423 if ((TheTriple.getArch() == Triple::mips) ||
424 (TheTriple.getArch() == Triple::mips64))
425 IsLittleEndian = false;
427 IsLittleEndian = true;
430 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
431 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
433 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
434 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
435 const MipsABIInfo &getABI() const { return ABI; }
436 bool isABI_N32() const { return ABI.IsN32(); }
437 bool isABI_N64() const { return ABI.IsN64(); }
438 bool isABI_O32() const { return ABI.IsO32(); }
439 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
441 bool useOddSPReg() const {
442 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
445 bool inMicroMipsMode() const {
446 return STI.getFeatureBits()[Mips::FeatureMicroMips];
448 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
449 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
450 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
451 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
452 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
453 bool hasMips32() const {
454 return STI.getFeatureBits()[Mips::FeatureMips32];
456 bool hasMips64() const {
457 return STI.getFeatureBits()[Mips::FeatureMips64];
459 bool hasMips32r2() const {
460 return STI.getFeatureBits()[Mips::FeatureMips32r2];
462 bool hasMips64r2() const {
463 return STI.getFeatureBits()[Mips::FeatureMips64r2];
465 bool hasMips32r3() const {
466 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
468 bool hasMips64r3() const {
469 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
471 bool hasMips32r5() const {
472 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
474 bool hasMips64r5() const {
475 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
477 bool hasMips32r6() const {
478 return STI.getFeatureBits()[Mips::FeatureMips32r6];
480 bool hasMips64r6() const {
481 return STI.getFeatureBits()[Mips::FeatureMips64r6];
484 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
485 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
486 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
487 bool hasCnMips() const {
488 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
495 bool inMips16Mode() const {
496 return STI.getFeatureBits()[Mips::FeatureMips16];
499 bool useTraps() const {
500 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
503 bool useSoftFloat() const {
504 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
507 /// Warn if RegIndex is the same as the current AT.
508 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
510 void warnIfNoMacro(SMLoc Loc);
512 bool isLittle() const { return IsLittleEndian; }
518 /// MipsOperand - Instances of this class represent a parsed Mips machine
520 class MipsOperand : public MCParsedAsmOperand {
522 /// Broad categories of register classes
523 /// The exact class is finalized by the render method.
525 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
526 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
528 RegKind_FCC = 4, /// FCC
529 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
530 RegKind_MSACtrl = 16, /// MSA control registers
531 RegKind_COP2 = 32, /// COP2
532 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
534 RegKind_CCR = 128, /// CCR
535 RegKind_HWRegs = 256, /// HWRegs
536 RegKind_COP3 = 512, /// COP3
537 RegKind_COP0 = 1024, /// COP0
538 /// Potentially any (e.g. $1)
539 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
540 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
541 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
546 k_Immediate, /// An immediate (possibly involving symbol references)
547 k_Memory, /// Base + Offset Memory Address
548 k_PhysRegister, /// A physical register from the Mips namespace
549 k_RegisterIndex, /// A register index in one or more RegKind.
550 k_Token, /// A simple token
551 k_RegList, /// A physical register list
552 k_RegPair /// A pair of physical register
556 MipsOperand(KindTy K, MipsAsmParser &Parser)
557 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
560 /// For diagnostics, and checking the assembler temporary
561 MipsAsmParser &AsmParser;
569 unsigned Num; /// Register Number
573 unsigned Index; /// Index into the register class
574 RegKind Kind; /// Bitfield of the kinds it could possibly be
575 const MCRegisterInfo *RegInfo;
588 SmallVector<unsigned, 10> *List;
593 struct PhysRegOp PhysReg;
594 struct RegIdxOp RegIdx;
597 struct RegListOp RegList;
600 SMLoc StartLoc, EndLoc;
602 /// Internal constructor for register kinds
603 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
604 const MCRegisterInfo *RegInfo,
606 MipsAsmParser &Parser) {
607 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
608 Op->RegIdx.Index = Index;
609 Op->RegIdx.RegInfo = RegInfo;
610 Op->RegIdx.Kind = RegKind;
617 /// Coerce the register to GPR32 and return the real register for the current
619 unsigned getGPR32Reg() const {
620 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
621 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
622 unsigned ClassID = Mips::GPR32RegClassID;
623 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
626 /// Coerce the register to GPR32 and return the real register for the current
628 unsigned getGPRMM16Reg() const {
629 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
630 unsigned ClassID = Mips::GPR32RegClassID;
631 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
634 /// Coerce the register to GPR64 and return the real register for the current
636 unsigned getGPR64Reg() const {
637 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
638 unsigned ClassID = Mips::GPR64RegClassID;
639 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
643 /// Coerce the register to AFGR64 and return the real register for the current
645 unsigned getAFGR64Reg() const {
646 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
647 if (RegIdx.Index % 2 != 0)
648 AsmParser.Warning(StartLoc, "Float register should be even.");
649 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
650 .getRegister(RegIdx.Index / 2);
653 /// Coerce the register to FGR64 and return the real register for the current
655 unsigned getFGR64Reg() const {
656 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
657 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
658 .getRegister(RegIdx.Index);
661 /// Coerce the register to FGR32 and return the real register for the current
663 unsigned getFGR32Reg() const {
664 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
665 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
666 .getRegister(RegIdx.Index);
669 /// Coerce the register to FGRH32 and return the real register for the current
671 unsigned getFGRH32Reg() const {
672 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
673 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
674 .getRegister(RegIdx.Index);
677 /// Coerce the register to FCC and return the real register for the current
679 unsigned getFCCReg() const {
680 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
681 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
682 .getRegister(RegIdx.Index);
685 /// Coerce the register to MSA128 and return the real register for the current
687 unsigned getMSA128Reg() const {
688 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
689 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
691 unsigned ClassID = Mips::MSA128BRegClassID;
692 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
695 /// Coerce the register to MSACtrl and return the real register for the
697 unsigned getMSACtrlReg() const {
698 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
699 unsigned ClassID = Mips::MSACtrlRegClassID;
700 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
703 /// Coerce the register to COP0 and return the real register for the
705 unsigned getCOP0Reg() const {
706 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
707 unsigned ClassID = Mips::COP0RegClassID;
708 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
711 /// Coerce the register to COP2 and return the real register for the
713 unsigned getCOP2Reg() const {
714 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
715 unsigned ClassID = Mips::COP2RegClassID;
716 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
719 /// Coerce the register to COP3 and return the real register for the
721 unsigned getCOP3Reg() const {
722 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
723 unsigned ClassID = Mips::COP3RegClassID;
724 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
727 /// Coerce the register to ACC64DSP and return the real register for the
729 unsigned getACC64DSPReg() const {
730 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
731 unsigned ClassID = Mips::ACC64DSPRegClassID;
732 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
735 /// Coerce the register to HI32DSP and return the real register for the
737 unsigned getHI32DSPReg() const {
738 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
739 unsigned ClassID = Mips::HI32DSPRegClassID;
740 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
743 /// Coerce the register to LO32DSP and return the real register for the
745 unsigned getLO32DSPReg() const {
746 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
747 unsigned ClassID = Mips::LO32DSPRegClassID;
748 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
751 /// Coerce the register to CCR and return the real register for the
753 unsigned getCCRReg() const {
754 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
755 unsigned ClassID = Mips::CCRRegClassID;
756 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
759 /// Coerce the register to HWRegs and return the real register for the
761 unsigned getHWRegsReg() const {
762 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
763 unsigned ClassID = Mips::HWRegsRegClassID;
764 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
768 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
769 // Add as immediate when possible. Null MCExpr = 0.
771 Inst.addOperand(MCOperand::createImm(0));
772 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
773 Inst.addOperand(MCOperand::createImm(CE->getValue()));
775 Inst.addOperand(MCOperand::createExpr(Expr));
778 void addRegOperands(MCInst &Inst, unsigned N) const {
779 llvm_unreachable("Use a custom parser instead");
782 /// Render the operand to an MCInst as a GPR32
783 /// Asserts if the wrong number of operands are requested, or the operand
784 /// is not a k_RegisterIndex compatible with RegKind_GPR
785 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
786 assert(N == 1 && "Invalid number of operands!");
787 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
790 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
791 assert(N == 1 && "Invalid number of operands!");
792 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
795 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
796 assert(N == 1 && "Invalid number of operands!");
797 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
800 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
801 assert(N == 1 && "Invalid number of operands!");
802 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
805 /// Render the operand to an MCInst as a GPR64
806 /// Asserts if the wrong number of operands are requested, or the operand
807 /// is not a k_RegisterIndex compatible with RegKind_GPR
808 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
809 assert(N == 1 && "Invalid number of operands!");
810 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
813 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 1 && "Invalid number of operands!");
815 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
818 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
819 assert(N == 1 && "Invalid number of operands!");
820 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
823 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
824 assert(N == 1 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
826 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
827 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
828 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
832 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
833 assert(N == 1 && "Invalid number of operands!");
834 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
837 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
838 assert(N == 1 && "Invalid number of operands!");
839 Inst.addOperand(MCOperand::createReg(getFCCReg()));
842 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
843 assert(N == 1 && "Invalid number of operands!");
844 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
847 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 1 && "Invalid number of operands!");
849 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
852 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
853 assert(N == 1 && "Invalid number of operands!");
854 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
857 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
858 assert(N == 1 && "Invalid number of operands!");
859 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
862 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
863 assert(N == 1 && "Invalid number of operands!");
864 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
867 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
868 assert(N == 1 && "Invalid number of operands!");
869 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
872 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
873 assert(N == 1 && "Invalid number of operands!");
874 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
877 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
878 assert(N == 1 && "Invalid number of operands!");
879 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
882 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
883 assert(N == 1 && "Invalid number of operands!");
884 Inst.addOperand(MCOperand::createReg(getCCRReg()));
887 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
888 assert(N == 1 && "Invalid number of operands!");
889 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
892 void addImmOperands(MCInst &Inst, unsigned N) const {
893 assert(N == 1 && "Invalid number of operands!");
894 const MCExpr *Expr = getImm();
898 void addMemOperands(MCInst &Inst, unsigned N) const {
899 assert(N == 2 && "Invalid number of operands!");
901 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
902 ? getMemBase()->getGPR64Reg()
903 : getMemBase()->getGPR32Reg()));
905 const MCExpr *Expr = getMemOff();
909 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
910 assert(N == 2 && "Invalid number of operands!");
912 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
914 const MCExpr *Expr = getMemOff();
918 void addRegListOperands(MCInst &Inst, unsigned N) const {
919 assert(N == 1 && "Invalid number of operands!");
921 for (auto RegNo : getRegList())
922 Inst.addOperand(MCOperand::createReg(RegNo));
925 void addRegPairOperands(MCInst &Inst, unsigned N) const {
926 assert(N == 2 && "Invalid number of operands!");
927 unsigned RegNo = getRegPair();
928 Inst.addOperand(MCOperand::createReg(RegNo++));
929 Inst.addOperand(MCOperand::createReg(RegNo));
932 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
933 assert(N == 2 && "Invalid number of operands!");
934 for (auto RegNo : getRegList())
935 Inst.addOperand(MCOperand::createReg(RegNo));
938 bool isReg() const override {
939 // As a special case until we sort out the definition of div/divu, pretend
940 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
941 if (isGPRAsmReg() && RegIdx.Index == 0)
944 return Kind == k_PhysRegister;
946 bool isRegIdx() const { return Kind == k_RegisterIndex; }
947 bool isImm() const override { return Kind == k_Immediate; }
948 bool isConstantImm() const {
949 return isImm() && dyn_cast<MCConstantExpr>(getImm());
951 template <unsigned Bits> bool isUImm() const {
952 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
954 bool isToken() const override {
955 // Note: It's not possible to pretend that other operand kinds are tokens.
956 // The matcher emitter checks tokens first.
957 return Kind == k_Token;
959 bool isMem() const override { return Kind == k_Memory; }
960 bool isConstantMemOff() const {
961 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
963 template <unsigned Bits> bool isMemWithSimmOffset() const {
964 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
965 && getMemBase()->isGPRAsmReg();
967 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
968 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
969 getMemBase()->isGPRAsmReg();
971 bool isMemWithGRPMM16Base() const {
972 return isMem() && getMemBase()->isMM16AsmReg();
974 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
975 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
976 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
978 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
979 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
980 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
981 && (getMemBase()->getGPR32Reg() == Mips::SP);
983 bool isUImm5Lsl2() const {
984 return (isImm() && isConstantImm() && isShiftedUInt<5, 2>(getConstantImm()));
986 bool isRegList16() const {
990 int Size = RegList.List->size();
991 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
992 RegList.List->back() != Mips::RA)
995 int PrevReg = *RegList.List->begin();
996 for (int i = 1; i < Size - 1; i++) {
997 int Reg = (*(RegList.List))[i];
998 if ( Reg != PrevReg + 1)
1005 bool isInvNum() const { return Kind == k_Immediate; }
1006 bool isLSAImm() const {
1007 if (!isConstantImm())
1009 int64_t Val = getConstantImm();
1010 return 1 <= Val && Val <= 4;
1012 bool isRegList() const { return Kind == k_RegList; }
1013 bool isMovePRegPair() const {
1014 if (Kind != k_RegList || RegList.List->size() != 2)
1017 unsigned R0 = RegList.List->front();
1018 unsigned R1 = RegList.List->back();
1020 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1021 (R0 == Mips::A1 && R1 == Mips::A3) ||
1022 (R0 == Mips::A2 && R1 == Mips::A3) ||
1023 (R0 == Mips::A0 && R1 == Mips::S5) ||
1024 (R0 == Mips::A0 && R1 == Mips::S6) ||
1025 (R0 == Mips::A0 && R1 == Mips::A1) ||
1026 (R0 == Mips::A0 && R1 == Mips::A2) ||
1027 (R0 == Mips::A0 && R1 == Mips::A3))
1033 StringRef getToken() const {
1034 assert(Kind == k_Token && "Invalid access!");
1035 return StringRef(Tok.Data, Tok.Length);
1037 bool isRegPair() const { return Kind == k_RegPair; }
1039 unsigned getReg() const override {
1040 // As a special case until we sort out the definition of div/divu, pretend
1041 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1042 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1043 RegIdx.Kind & RegKind_GPR)
1044 return getGPR32Reg(); // FIXME: GPR64 too
1046 assert(Kind == k_PhysRegister && "Invalid access!");
1050 const MCExpr *getImm() const {
1051 assert((Kind == k_Immediate) && "Invalid access!");
1055 int64_t getConstantImm() const {
1056 const MCExpr *Val = getImm();
1057 return static_cast<const MCConstantExpr *>(Val)->getValue();
1060 MipsOperand *getMemBase() const {
1061 assert((Kind == k_Memory) && "Invalid access!");
1065 const MCExpr *getMemOff() const {
1066 assert((Kind == k_Memory) && "Invalid access!");
1070 int64_t getConstantMemOff() const {
1071 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1074 const SmallVectorImpl<unsigned> &getRegList() const {
1075 assert((Kind == k_RegList) && "Invalid access!");
1076 return *(RegList.List);
1079 unsigned getRegPair() const {
1080 assert((Kind == k_RegPair) && "Invalid access!");
1081 return RegIdx.Index;
1084 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1085 MipsAsmParser &Parser) {
1086 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1087 Op->Tok.Data = Str.data();
1088 Op->Tok.Length = Str.size();
1094 /// Create a numeric register (e.g. $1). The exact register remains
1095 /// unresolved until an instruction successfully matches
1096 static std::unique_ptr<MipsOperand>
1097 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1098 SMLoc E, MipsAsmParser &Parser) {
1099 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1100 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1103 /// Create a register that is definitely a GPR.
1104 /// This is typically only used for named registers such as $gp.
1105 static std::unique_ptr<MipsOperand>
1106 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1107 MipsAsmParser &Parser) {
1108 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1111 /// Create a register that is definitely a FGR.
1112 /// This is typically only used for named registers such as $f0.
1113 static std::unique_ptr<MipsOperand>
1114 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1115 MipsAsmParser &Parser) {
1116 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1119 /// Create a register that is definitely a HWReg.
1120 /// This is typically only used for named registers such as $hwr_cpunum.
1121 static std::unique_ptr<MipsOperand>
1122 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1123 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1124 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1127 /// Create a register that is definitely an FCC.
1128 /// This is typically only used for named registers such as $fcc0.
1129 static std::unique_ptr<MipsOperand>
1130 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1131 MipsAsmParser &Parser) {
1132 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1135 /// Create a register that is definitely an ACC.
1136 /// This is typically only used for named registers such as $ac0.
1137 static std::unique_ptr<MipsOperand>
1138 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1139 MipsAsmParser &Parser) {
1140 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1143 /// Create a register that is definitely an MSA128.
1144 /// This is typically only used for named registers such as $w0.
1145 static std::unique_ptr<MipsOperand>
1146 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1147 SMLoc E, MipsAsmParser &Parser) {
1148 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1151 /// Create a register that is definitely an MSACtrl.
1152 /// This is typically only used for named registers such as $msaaccess.
1153 static std::unique_ptr<MipsOperand>
1154 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1155 SMLoc E, MipsAsmParser &Parser) {
1156 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1159 static std::unique_ptr<MipsOperand>
1160 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1161 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1168 static std::unique_ptr<MipsOperand>
1169 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1170 SMLoc E, MipsAsmParser &Parser) {
1171 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1172 Op->Mem.Base = Base.release();
1179 static std::unique_ptr<MipsOperand>
1180 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1181 MipsAsmParser &Parser) {
1182 assert (Regs.size() > 0 && "Empty list not allowed");
1184 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1185 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1186 Op->StartLoc = StartLoc;
1187 Op->EndLoc = EndLoc;
1191 static std::unique_ptr<MipsOperand>
1192 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1193 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1194 Op->RegIdx.Index = RegNo;
1200 bool isGPRAsmReg() const {
1201 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1203 bool isMM16AsmReg() const {
1204 if (!(isRegIdx() && RegIdx.Kind))
1206 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1207 || RegIdx.Index == 16 || RegIdx.Index == 17);
1209 bool isMM16AsmRegZero() const {
1210 if (!(isRegIdx() && RegIdx.Kind))
1212 return (RegIdx.Index == 0 ||
1213 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1214 RegIdx.Index == 17);
1216 bool isMM16AsmRegMoveP() const {
1217 if (!(isRegIdx() && RegIdx.Kind))
1219 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1220 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1222 bool isFGRAsmReg() const {
1223 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1224 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1226 bool isHWRegsAsmReg() const {
1227 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1229 bool isCCRAsmReg() const {
1230 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1232 bool isFCCAsmReg() const {
1233 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1235 if (!AsmParser.hasEightFccRegisters())
1236 return RegIdx.Index == 0;
1237 return RegIdx.Index <= 7;
1239 bool isACCAsmReg() const {
1240 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1242 bool isCOP0AsmReg() const {
1243 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1245 bool isCOP2AsmReg() const {
1246 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1248 bool isCOP3AsmReg() const {
1249 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1251 bool isMSA128AsmReg() const {
1252 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1254 bool isMSACtrlAsmReg() const {
1255 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1258 /// getStartLoc - Get the location of the first token of this operand.
1259 SMLoc getStartLoc() const override { return StartLoc; }
1260 /// getEndLoc - Get the location of the last token of this operand.
1261 SMLoc getEndLoc() const override { return EndLoc; }
1263 virtual ~MipsOperand() {
1271 delete RegList.List;
1272 case k_PhysRegister:
1273 case k_RegisterIndex:
1280 void print(raw_ostream &OS) const override {
1289 Mem.Base->print(OS);
1294 case k_PhysRegister:
1295 OS << "PhysReg<" << PhysReg.Num << ">";
1297 case k_RegisterIndex:
1298 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1305 for (auto Reg : (*RegList.List))
1310 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1314 }; // class MipsOperand
1318 extern const MCInstrDesc MipsInsts[];
1320 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1321 return MipsInsts[Opcode];
1324 static bool hasShortDelaySlot(unsigned Opcode) {
1327 case Mips::JALRS_MM:
1328 case Mips::JALRS16_MM:
1329 case Mips::BGEZALS_MM:
1330 case Mips::BLTZALS_MM:
1337 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1338 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1339 return &SRExpr->getSymbol();
1342 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1343 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1344 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1355 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1356 return getSingleMCSymbol(UExpr->getSubExpr());
1361 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1362 if (isa<MCSymbolRefExpr>(Expr))
1365 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1366 return countMCSymbolRefExpr(BExpr->getLHS()) +
1367 countMCSymbolRefExpr(BExpr->getRHS());
1369 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1370 return countMCSymbolRefExpr(UExpr->getSubExpr());
1376 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1377 SmallVectorImpl<MCInst> &Instructions) {
1379 tmpInst.setOpcode(Opcode);
1380 tmpInst.addOperand(MCOperand::createReg(Reg0));
1381 tmpInst.addOperand(Op1);
1382 tmpInst.setLoc(IDLoc);
1383 Instructions.push_back(tmpInst);
1386 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1387 SmallVectorImpl<MCInst> &Instructions) {
1388 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1391 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1392 SmallVectorImpl<MCInst> &Instructions) {
1393 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1396 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1397 SmallVectorImpl<MCInst> &Instructions) {
1399 tmpInst.setOpcode(Opcode);
1400 tmpInst.addOperand(MCOperand::createImm(Imm1));
1401 tmpInst.addOperand(MCOperand::createImm(Imm2));
1402 tmpInst.setLoc(IDLoc);
1403 Instructions.push_back(tmpInst);
1406 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1407 SmallVectorImpl<MCInst> &Instructions) {
1409 tmpInst.setOpcode(Opcode);
1410 tmpInst.addOperand(MCOperand::createReg(Reg0));
1411 tmpInst.setLoc(IDLoc);
1412 Instructions.push_back(tmpInst);
1415 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1416 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1418 tmpInst.setOpcode(Opcode);
1419 tmpInst.addOperand(MCOperand::createReg(Reg0));
1420 tmpInst.addOperand(MCOperand::createReg(Reg1));
1421 tmpInst.addOperand(Op2);
1422 tmpInst.setLoc(IDLoc);
1423 Instructions.push_back(tmpInst);
1426 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1427 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1428 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1432 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1433 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1434 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1438 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1439 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1440 if (ShiftAmount >= 32) {
1441 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1446 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1448 } // end anonymous namespace.
1450 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1451 SmallVectorImpl<MCInst> &Instructions) {
1452 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1453 bool ExpandedJalSym = false;
1457 if (MCID.isBranch() || MCID.isCall()) {
1458 const unsigned Opcode = Inst.getOpcode();
1468 assert(hasCnMips() && "instruction only valid for octeon cpus");
1475 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1476 Offset = Inst.getOperand(2);
1477 if (!Offset.isImm())
1478 break; // We'll deal with this situation later on when applying fixups.
1479 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1480 return Error(IDLoc, "branch target out of range");
1481 if (OffsetToAlignment(Offset.getImm(),
1482 1LL << (inMicroMipsMode() ? 1 : 2)))
1483 return Error(IDLoc, "branch to misaligned address");
1497 case Mips::BGEZAL_MM:
1498 case Mips::BLTZAL_MM:
1501 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1502 Offset = Inst.getOperand(1);
1503 if (!Offset.isImm())
1504 break; // We'll deal with this situation later on when applying fixups.
1505 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1506 return Error(IDLoc, "branch target out of range");
1507 if (OffsetToAlignment(Offset.getImm(),
1508 1LL << (inMicroMipsMode() ? 1 : 2)))
1509 return Error(IDLoc, "branch to misaligned address");
1511 case Mips::BEQZ16_MM:
1512 case Mips::BEQZC16_MMR6:
1513 case Mips::BNEZ16_MM:
1514 case Mips::BNEZC16_MMR6:
1515 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1516 Offset = Inst.getOperand(1);
1517 if (!Offset.isImm())
1518 break; // We'll deal with this situation later on when applying fixups.
1519 if (!isInt<8>(Offset.getImm()))
1520 return Error(IDLoc, "branch target out of range");
1521 if (OffsetToAlignment(Offset.getImm(), 2LL))
1522 return Error(IDLoc, "branch to misaligned address");
1527 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1528 // We still accept it but it is a normal nop.
1529 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1530 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1531 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1536 const unsigned Opcode = Inst.getOpcode();
1548 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1549 // The offset is handled above
1550 Opnd = Inst.getOperand(1);
1552 return Error(IDLoc, "expected immediate operand kind");
1553 Imm = Opnd.getImm();
1554 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1555 Opcode == Mips::BBIT1 ? 63 : 31))
1556 return Error(IDLoc, "immediate operand value out of range");
1558 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1560 Inst.getOperand(1).setImm(Imm - 32);
1568 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1570 Opnd = Inst.getOperand(3);
1572 return Error(IDLoc, "expected immediate operand kind");
1573 Imm = Opnd.getImm();
1574 if (Imm < 0 || Imm > 31)
1575 return Error(IDLoc, "immediate operand value out of range");
1577 Opnd = Inst.getOperand(2);
1579 return Error(IDLoc, "expected immediate operand kind");
1580 Imm = Opnd.getImm();
1581 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1582 Opcode == Mips::EXTS ? 63 : 31))
1583 return Error(IDLoc, "immediate operand value out of range");
1585 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1586 Inst.getOperand(2).setImm(Imm - 32);
1592 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1593 Opnd = Inst.getOperand(2);
1595 return Error(IDLoc, "expected immediate operand kind");
1596 Imm = Opnd.getImm();
1597 if (!isInt<10>(Imm))
1598 return Error(IDLoc, "immediate operand value out of range");
1603 // This expansion is not in a function called by expandInstruction() because
1604 // the pseudo-instruction doesn't have a distinct opcode.
1605 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1607 warnIfNoMacro(IDLoc);
1609 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1611 // We can do this expansion if there's only 1 symbol in the argument
1613 if (countMCSymbolRefExpr(JalExpr) > 1)
1614 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1616 // FIXME: This is checking the expression can be handled by the later stages
1617 // of the assembler. We ought to leave it to those later stages but
1618 // we can't do that until we stop evaluateRelocExpr() rewriting the
1619 // expressions into non-equivalent forms.
1620 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1622 // FIXME: Add support for label+offset operands (currently causes an error).
1623 // FIXME: Add support for forward-declared local symbols.
1624 // FIXME: Add expansion for when the LargeGOT option is enabled.
1625 if (JalSym->isInSection() || JalSym->isTemporary()) {
1627 // If it's a local symbol and the O32 ABI is being used, we expand to:
1629 // R_(MICRO)MIPS_GOT16 label
1630 // addiu $25, $25, 0
1631 // R_(MICRO)MIPS_LO16 label
1633 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1634 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1636 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1637 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1638 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1639 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1640 } else if (isABI_N32() || isABI_N64()) {
1641 // If it's a local symbol and the N32/N64 ABIs are being used,
1643 // lw/ld $25, 0($gp)
1644 // R_(MICRO)MIPS_GOT_DISP label
1646 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1648 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1649 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1652 // If it's an external/weak symbol, we expand to:
1653 // lw/ld $25, 0($gp)
1654 // R_(MICRO)MIPS_CALL16 label
1656 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1658 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1659 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1663 if (IsCpRestoreSet && inMicroMipsMode())
1664 JalrInst.setOpcode(Mips::JALRS_MM);
1666 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1667 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1668 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1670 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1671 // This relocation is supposed to be an optimization hint for the linker
1672 // and is not necessary for correctness.
1675 ExpandedJalSym = true;
1678 if (MCID.mayLoad() || MCID.mayStore()) {
1679 // Check the offset of memory operand, if it is a symbol
1680 // reference or immediate we may have to expand instructions.
1681 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1682 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1683 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1684 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1685 MCOperand &Op = Inst.getOperand(i);
1687 int MemOffset = Op.getImm();
1688 if (MemOffset < -32768 || MemOffset > 32767) {
1689 // Offset can't exceed 16bit value.
1690 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1693 } else if (Op.isExpr()) {
1694 const MCExpr *Expr = Op.getExpr();
1695 if (Expr->getKind() == MCExpr::SymbolRef) {
1696 const MCSymbolRefExpr *SR =
1697 static_cast<const MCSymbolRefExpr *>(Expr);
1698 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1700 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1703 } else if (!isEvaluated(Expr)) {
1704 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1712 if (inMicroMipsMode()) {
1713 if (MCID.mayLoad()) {
1714 // Try to create 16-bit GP relative load instruction.
1715 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1716 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1717 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1718 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1719 MCOperand &Op = Inst.getOperand(i);
1721 int MemOffset = Op.getImm();
1722 MCOperand &DstReg = Inst.getOperand(0);
1723 MCOperand &BaseReg = Inst.getOperand(1);
1724 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1725 getContext().getRegisterInfo()->getRegClass(
1726 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1727 (BaseReg.getReg() == Mips::GP ||
1728 BaseReg.getReg() == Mips::GP_64)) {
1730 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1731 IDLoc, Instructions);
1739 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1744 switch (Inst.getOpcode()) {
1747 case Mips::ADDIUS5_MM:
1748 Opnd = Inst.getOperand(2);
1750 return Error(IDLoc, "expected immediate operand kind");
1751 Imm = Opnd.getImm();
1752 if (Imm < -8 || Imm > 7)
1753 return Error(IDLoc, "immediate operand value out of range");
1755 case Mips::ADDIUSP_MM:
1756 Opnd = Inst.getOperand(0);
1758 return Error(IDLoc, "expected immediate operand kind");
1759 Imm = Opnd.getImm();
1760 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1762 return Error(IDLoc, "immediate operand value out of range");
1764 case Mips::SLL16_MM:
1765 case Mips::SRL16_MM:
1766 Opnd = Inst.getOperand(2);
1768 return Error(IDLoc, "expected immediate operand kind");
1769 Imm = Opnd.getImm();
1770 if (Imm < 1 || Imm > 8)
1771 return Error(IDLoc, "immediate operand value out of range");
1774 Opnd = Inst.getOperand(1);
1776 return Error(IDLoc, "expected immediate operand kind");
1777 Imm = Opnd.getImm();
1778 if (Imm < -1 || Imm > 126)
1779 return Error(IDLoc, "immediate operand value out of range");
1781 case Mips::ADDIUR2_MM:
1782 Opnd = Inst.getOperand(2);
1784 return Error(IDLoc, "expected immediate operand kind");
1785 Imm = Opnd.getImm();
1786 if (!(Imm == 1 || Imm == -1 ||
1787 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1788 return Error(IDLoc, "immediate operand value out of range");
1790 case Mips::ADDIUR1SP_MM:
1791 Opnd = Inst.getOperand(1);
1793 return Error(IDLoc, "expected immediate operand kind");
1794 Imm = Opnd.getImm();
1795 if (OffsetToAlignment(Imm, 4LL))
1796 return Error(IDLoc, "misaligned immediate operand value");
1797 if (Imm < 0 || Imm > 255)
1798 return Error(IDLoc, "immediate operand value out of range");
1800 case Mips::ANDI16_MM:
1801 Opnd = Inst.getOperand(2);
1803 return Error(IDLoc, "expected immediate operand kind");
1804 Imm = Opnd.getImm();
1805 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1806 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1807 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1808 return Error(IDLoc, "immediate operand value out of range");
1810 case Mips::LBU16_MM:
1811 Opnd = Inst.getOperand(2);
1813 return Error(IDLoc, "expected immediate operand kind");
1814 Imm = Opnd.getImm();
1815 if (Imm < -1 || Imm > 14)
1816 return Error(IDLoc, "immediate operand value out of range");
1825 Opnd = Inst.getOperand(2);
1827 return Error(IDLoc, "expected immediate operand kind");
1828 Imm = Opnd.getImm();
1829 if (Imm < 0 || Imm > 15)
1830 return Error(IDLoc, "immediate operand value out of range");
1832 case Mips::LHU16_MM:
1834 Opnd = Inst.getOperand(2);
1836 return Error(IDLoc, "expected immediate operand kind");
1837 Imm = Opnd.getImm();
1838 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1839 return Error(IDLoc, "immediate operand value out of range");
1843 Opnd = Inst.getOperand(2);
1845 return Error(IDLoc, "expected immediate operand kind");
1846 Imm = Opnd.getImm();
1847 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1848 return Error(IDLoc, "immediate operand value out of range");
1850 case Mips::PREFX_MM:
1853 Opnd = Inst.getOperand(2);
1855 return Error(IDLoc, "expected immediate operand kind");
1856 Imm = Opnd.getImm();
1857 if (!isUInt<5>(Imm))
1858 return Error(IDLoc, "immediate operand value out of range");
1860 case Mips::ADDIUPC_MM:
1861 MCOperand Opnd = Inst.getOperand(1);
1863 return Error(IDLoc, "expected immediate operand kind");
1864 int Imm = Opnd.getImm();
1865 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1866 return Error(IDLoc, "immediate operand value out of range");
1871 if (needsExpansion(Inst)) {
1872 if (expandInstruction(Inst, IDLoc, Instructions))
1875 Instructions.push_back(Inst);
1877 // If this instruction has a delay slot and .set reorder is active,
1878 // emit a NOP after it.
1879 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1880 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1882 if ((Inst.getOpcode() == Mips::JalOneReg ||
1883 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1884 isPicAndNotNxxAbi()) {
1885 if (IsCpRestoreSet) {
1886 // We need a NOP between the JALR and the LW:
1887 // If .set reorder has been used, we've already emitted a NOP.
1888 // If .set noreorder has been used, we need to emit a NOP at this point.
1889 if (!AssemblerOptions.back()->isReorder())
1890 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1892 // Load the $gp from the stack.
1893 SmallVector<MCInst, 3> LoadInsts;
1894 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1897 for (const MCInst &Inst : LoadInsts)
1898 Instructions.push_back(Inst);
1901 Warning(IDLoc, "no .cprestore used in PIC mode");
1907 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1909 switch (Inst.getOpcode()) {
1910 case Mips::LoadImm32:
1911 case Mips::LoadImm64:
1912 case Mips::LoadAddrImm32:
1913 case Mips::LoadAddrImm64:
1914 case Mips::LoadAddrReg32:
1915 case Mips::LoadAddrReg64:
1916 case Mips::B_MM_Pseudo:
1917 case Mips::B_MMR6_Pseudo:
1920 case Mips::JalOneReg:
1921 case Mips::JalTwoReg:
1940 case Mips::SDivMacro:
1941 case Mips::UDivMacro:
1942 case Mips::DSDivMacro:
1943 case Mips::DUDivMacro:
1952 if ((Inst.getNumOperands() == 3) &&
1953 Inst.getOperand(0).isReg() &&
1954 Inst.getOperand(1).isReg() &&
1955 Inst.getOperand(2).isImm()) {
1956 int64_t ImmValue = Inst.getOperand(2).getImm();
1957 return !isInt<16>(ImmValue);
1963 if ((Inst.getNumOperands() == 3) &&
1964 Inst.getOperand(0).isReg() &&
1965 Inst.getOperand(1).isReg() &&
1966 Inst.getOperand(2).isImm()) {
1967 int64_t ImmValue = Inst.getOperand(2).getImm();
1968 return !isUInt<16>(ImmValue);
1976 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1977 SmallVectorImpl<MCInst> &Instructions) {
1978 switch (Inst.getOpcode()) {
1979 default: llvm_unreachable("unimplemented expansion");
1980 case Mips::LoadImm32:
1981 return expandLoadImm(Inst, true, IDLoc, Instructions);
1982 case Mips::LoadImm64:
1983 return expandLoadImm(Inst, false, IDLoc, Instructions);
1984 case Mips::LoadAddrImm32:
1985 case Mips::LoadAddrImm64:
1986 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1987 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1988 "expected immediate operand kind");
1990 return expandLoadAddress(
1991 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1992 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1993 case Mips::LoadAddrReg32:
1994 case Mips::LoadAddrReg64:
1995 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1996 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1997 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1998 "expected immediate operand kind");
2000 return expandLoadAddress(
2001 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
2002 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
2003 case Mips::B_MM_Pseudo:
2004 case Mips::B_MMR6_Pseudo:
2005 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
2008 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
2009 case Mips::JalOneReg:
2010 case Mips::JalTwoReg:
2011 return expandJalWithRegs(Inst, IDLoc, Instructions);
2014 return expandBranchImm(Inst, IDLoc, Instructions);
2031 return expandCondBranches(Inst, IDLoc, Instructions);
2032 case Mips::SDivMacro:
2033 return expandDiv(Inst, IDLoc, Instructions, false, true);
2034 case Mips::DSDivMacro:
2035 return expandDiv(Inst, IDLoc, Instructions, true, true);
2036 case Mips::UDivMacro:
2037 return expandDiv(Inst, IDLoc, Instructions, false, false);
2038 case Mips::DUDivMacro:
2039 return expandDiv(Inst, IDLoc, Instructions, true, false);
2041 return expandUlhu(Inst, IDLoc, Instructions);
2043 return expandUlw(Inst, IDLoc, Instructions);
2052 return expandAliasImmediate(Inst, IDLoc, Instructions);
2056 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2057 SmallVectorImpl<MCInst> &Instructions) {
2058 // Create a JALR instruction which is going to replace the pseudo-JAL.
2060 JalrInst.setLoc(IDLoc);
2061 const MCOperand FirstRegOp = Inst.getOperand(0);
2062 const unsigned Opcode = Inst.getOpcode();
2064 if (Opcode == Mips::JalOneReg) {
2065 // jal $rs => jalr $rs
2066 if (IsCpRestoreSet && inMicroMipsMode()) {
2067 JalrInst.setOpcode(Mips::JALRS16_MM);
2068 JalrInst.addOperand(FirstRegOp);
2069 } else if (inMicroMipsMode()) {
2070 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2071 JalrInst.addOperand(FirstRegOp);
2073 JalrInst.setOpcode(Mips::JALR);
2074 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2075 JalrInst.addOperand(FirstRegOp);
2077 } else if (Opcode == Mips::JalTwoReg) {
2078 // jal $rd, $rs => jalr $rd, $rs
2079 if (IsCpRestoreSet && inMicroMipsMode())
2080 JalrInst.setOpcode(Mips::JALRS_MM);
2082 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2083 JalrInst.addOperand(FirstRegOp);
2084 const MCOperand SecondRegOp = Inst.getOperand(1);
2085 JalrInst.addOperand(SecondRegOp);
2087 Instructions.push_back(JalrInst);
2089 // If .set reorder is active and branch instruction has a delay slot,
2090 // emit a NOP after it.
2091 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2092 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2093 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2099 /// Can the value be represented by a unsigned N-bit value and a shift left?
2100 template<unsigned N>
2101 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2102 unsigned BitNum = findFirstSet(x);
2104 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2107 /// Load (or add) an immediate into a register.
2109 /// @param ImmValue The immediate to load.
2110 /// @param DstReg The register that will hold the immediate.
2111 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2112 /// for a simple initialization.
2113 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2114 /// @param IsAddress True if the immediate represents an address. False if it
2116 /// @param IDLoc Location of the immediate in the source file.
2117 /// @param Instructions The instructions emitted by this expansion.
2118 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2119 unsigned SrcReg, bool Is32BitImm,
2120 bool IsAddress, SMLoc IDLoc,
2121 SmallVectorImpl<MCInst> &Instructions) {
2122 if (!Is32BitImm && !isGP64bit()) {
2123 Error(IDLoc, "instruction requires a 64-bit architecture");
2128 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2129 // Sign extend up to 64-bit so that the predicates match the hardware
2130 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2132 ImmValue = SignExtend64<32>(ImmValue);
2134 Error(IDLoc, "instruction requires a 32-bit immediate");
2139 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2140 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2142 bool UseSrcReg = false;
2143 if (SrcReg != Mips::NoRegister)
2146 unsigned TmpReg = DstReg;
2147 if (UseSrcReg && (DstReg == SrcReg)) {
2148 // At this point we need AT to perform the expansions and we exit if it is
2150 unsigned ATReg = getATReg(IDLoc);
2156 if (isInt<16>(ImmValue)) {
2160 // This doesn't quite follow the usual ABI expectations for N32 but matches
2161 // traditional assembler behaviour. N32 would normally use addiu for both
2162 // integers and addresses.
2163 if (IsAddress && !Is32BitImm) {
2164 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2168 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2172 if (isUInt<16>(ImmValue)) {
2173 unsigned TmpReg = DstReg;
2174 if (SrcReg == DstReg) {
2175 TmpReg = getATReg(IDLoc);
2180 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2182 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2186 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2187 warnIfNoMacro(IDLoc);
2189 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2190 uint16_t Bits15To0 = ImmValue & 0xffff;
2192 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2193 // Traditional behaviour seems to special case this particular value. It's
2194 // not clear why other masks are handled differently.
2195 if (ImmValue == 0xffffffff) {
2196 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2197 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2199 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2203 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2205 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2206 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2208 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2210 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2214 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2216 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2218 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2222 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2224 Error(IDLoc, "instruction requires a 32-bit immediate");
2228 // Traditionally, these immediates are shifted as little as possible and as
2229 // such we align the most significant bit to bit 15 of our temporary.
2230 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2231 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2232 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2233 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2234 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2235 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2238 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2243 warnIfNoMacro(IDLoc);
2245 // The remaining case is packed with a sequence of dsll and ori with zeros
2246 // being omitted and any neighbouring dsll's being coalesced.
2247 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2249 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2250 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2251 IDLoc, Instructions))
2254 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2255 // skip it and defer the shift to the next chunk.
2256 unsigned ShiftCarriedForwards = 16;
2257 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2258 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2260 if (ImmChunk != 0) {
2261 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2263 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2264 ShiftCarriedForwards = 0;
2267 ShiftCarriedForwards += 16;
2269 ShiftCarriedForwards -= 16;
2271 // Finish any remaining shifts left by trailing zeros.
2272 if (ShiftCarriedForwards)
2273 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2277 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2282 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2283 SmallVectorImpl<MCInst> &Instructions) {
2284 const MCOperand &ImmOp = Inst.getOperand(1);
2285 assert(ImmOp.isImm() && "expected immediate operand kind");
2286 const MCOperand &DstRegOp = Inst.getOperand(0);
2287 assert(DstRegOp.isReg() && "expected register operand kind");
2289 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2290 Is32BitImm, false, IDLoc, Instructions))
2296 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2297 const MCOperand &Offset,
2298 bool Is32BitAddress, SMLoc IDLoc,
2299 SmallVectorImpl<MCInst> &Instructions) {
2300 // la can't produce a usable address when addresses are 64-bit.
2301 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2302 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2303 // We currently can't do this because we depend on the equality
2304 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2305 Error(IDLoc, "la used to load 64-bit address");
2306 // Continue as if we had 'dla' instead.
2307 Is32BitAddress = false;
2310 // dla requires 64-bit addresses.
2311 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2312 Error(IDLoc, "instruction requires a 64-bit architecture");
2316 if (!Offset.isImm())
2317 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2318 Is32BitAddress, IDLoc, Instructions);
2320 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2321 IDLoc, Instructions);
2324 bool MipsAsmParser::loadAndAddSymbolAddress(
2325 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2326 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2327 warnIfNoMacro(IDLoc);
2329 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2330 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2331 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2332 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2333 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2335 bool UseSrcReg = SrcReg != Mips::NoRegister;
2337 // This is the 64-bit symbol address expansion.
2338 if (ABI.ArePtrs64bit() && isGP64bit()) {
2339 // We always need AT for the 64-bit expansion.
2340 // If it is not available we exit.
2341 unsigned ATReg = getATReg(IDLoc);
2345 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2346 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2347 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2348 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2350 if (UseSrcReg && (DstReg == SrcReg)) {
2351 // If $rs is the same as $rd:
2352 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2353 // daddiu $at, $at, %higher(sym)
2354 // dsll $at, $at, 16
2355 // daddiu $at, $at, %hi(sym)
2356 // dsll $at, $at, 16
2357 // daddiu $at, $at, %lo(sym)
2358 // daddu $rd, $at, $rd
2359 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2361 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2362 IDLoc, Instructions);
2363 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2364 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2366 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2367 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2369 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2374 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2375 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2376 // lui $at, %hi(sym)
2377 // daddiu $rd, $rd, %higher(sym)
2378 // daddiu $at, $at, %lo(sym)
2379 // dsll32 $rd, $rd, 0
2380 // daddu $rd, $rd, $at
2381 // (daddu $rd, $rd, $rs)
2382 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2384 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2386 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2387 IDLoc, Instructions);
2388 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2390 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2391 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2393 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2398 // And now, the 32-bit symbol address expansion:
2399 // If $rs is the same as $rd:
2400 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2401 // ori $at, $at, %lo(sym)
2402 // addu $rd, $at, $rd
2403 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2404 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2405 // ori $rd, $rd, %lo(sym)
2406 // (addu $rd, $rd, $rs)
2407 unsigned TmpReg = DstReg;
2408 if (UseSrcReg && (DstReg == SrcReg)) {
2409 // If $rs is the same as $rd, we need to use AT.
2410 // If it is not available we exit.
2411 unsigned ATReg = getATReg(IDLoc);
2417 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2418 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2422 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2424 assert(DstReg == TmpReg);
2429 bool MipsAsmParser::expandUncondBranchMMPseudo(
2430 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2431 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2432 "unexpected number of operands");
2434 MCOperand Offset = Inst.getOperand(0);
2435 if (Offset.isExpr()) {
2437 Inst.setOpcode(Mips::BEQ_MM);
2438 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2439 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2440 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2442 assert(Offset.isImm() && "expected immediate operand kind");
2443 if (isInt<11>(Offset.getImm())) {
2444 // If offset fits into 11 bits then this instruction becomes microMIPS
2445 // 16-bit unconditional branch instruction.
2446 if (inMicroMipsMode())
2447 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2449 if (!isInt<17>(Offset.getImm()))
2450 Error(IDLoc, "branch target out of range");
2451 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2452 Error(IDLoc, "branch to misaligned address");
2454 Inst.setOpcode(Mips::BEQ_MM);
2455 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2456 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2457 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2460 Instructions.push_back(Inst);
2462 // If .set reorder is active and branch instruction has a delay slot,
2463 // emit a NOP after it.
2464 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2465 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2466 createNop(true, IDLoc, Instructions);
2471 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2472 SmallVectorImpl<MCInst> &Instructions) {
2473 const MCOperand &DstRegOp = Inst.getOperand(0);
2474 assert(DstRegOp.isReg() && "expected register operand kind");
2476 const MCOperand &ImmOp = Inst.getOperand(1);
2477 assert(ImmOp.isImm() && "expected immediate operand kind");
2479 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2480 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2482 unsigned OpCode = 0;
2483 switch(Inst.getOpcode()) {
2491 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2495 int64_t ImmValue = ImmOp.getImm();
2497 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2500 warnIfNoMacro(IDLoc);
2502 unsigned ATReg = getATReg(IDLoc);
2506 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2507 IDLoc, Instructions))
2510 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2515 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2516 SmallVectorImpl<MCInst> &Instructions,
2517 bool isLoad, bool isImmOpnd) {
2518 unsigned ImmOffset, HiOffset, LoOffset;
2519 const MCExpr *ExprOffset;
2521 // 1st operand is either the source or destination register.
2522 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2523 unsigned RegOpNum = Inst.getOperand(0).getReg();
2524 // 2nd operand is the base register.
2525 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2526 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2527 // 3rd operand is either an immediate or expression.
2529 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2530 ImmOffset = Inst.getOperand(2).getImm();
2531 LoOffset = ImmOffset & 0x0000ffff;
2532 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2533 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2534 if (LoOffset & 0x8000)
2537 ExprOffset = Inst.getOperand(2).getExpr();
2538 // These are some of the types of expansions we perform here:
2539 // 1) lw $8, sym => lui $8, %hi(sym)
2540 // lw $8, %lo(sym)($8)
2541 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2543 // lw $8, %lo(offset)($9)
2544 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2546 // lw $8, %lo(offset)($at)
2547 // 4) sw $8, sym => lui $at, %hi(sym)
2548 // sw $8, %lo(sym)($at)
2549 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2551 // sw $8, %lo(offset)($at)
2552 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2553 // ldc1 $f0, %lo(sym)($at)
2555 // For load instructions we can use the destination register as a temporary
2556 // if base and dst are different (examples 1 and 2) and if the base register
2557 // is general purpose otherwise we must use $at (example 6) and error if it's
2558 // not available. For stores we must use $at (examples 4 and 5) because we
2559 // must not clobber the source register setting up the offset.
2560 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2561 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2562 unsigned RegClassIDOp0 =
2563 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2564 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2565 (RegClassIDOp0 == Mips::GPR64RegClassID);
2566 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2567 TmpRegNum = RegOpNum;
2569 // At this point we need AT to perform the expansions and we exit if it is
2571 TmpRegNum = getATReg(IDLoc);
2576 emitRX(Mips::LUi, TmpRegNum,
2577 isImmOpnd ? MCOperand::createImm(HiOffset)
2578 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2579 IDLoc, Instructions);
2580 // Add temp register to base.
2581 if (BaseRegNum != Mips::ZERO)
2582 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2583 // And finally, create original instruction with low part
2584 // of offset and new base.
2585 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2587 ? MCOperand::createImm(LoOffset)
2588 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2589 IDLoc, Instructions);
2593 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2594 SmallVectorImpl<MCInst> &Instructions) {
2595 unsigned OpNum = Inst.getNumOperands();
2596 unsigned Opcode = Inst.getOpcode();
2597 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2599 assert (Inst.getOperand(OpNum - 1).isImm() &&
2600 Inst.getOperand(OpNum - 2).isReg() &&
2601 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2603 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2604 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2605 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2606 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2607 // It can be implemented as SWM16 or LWM16 instruction.
2608 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2610 Inst.setOpcode(NewOpcode);
2611 Instructions.push_back(Inst);
2615 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2616 SmallVectorImpl<MCInst> &Instructions) {
2617 unsigned PseudoOpcode = Inst.getOpcode();
2618 unsigned SrcReg = Inst.getOperand(0).getReg();
2619 unsigned TrgReg = Inst.getOperand(1).getReg();
2620 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2622 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2623 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2625 switch (PseudoOpcode) {
2630 AcceptsEquality = false;
2631 ReverseOrderSLT = false;
2632 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2633 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2634 ZeroSrcOpcode = Mips::BGTZ;
2635 ZeroTrgOpcode = Mips::BLTZ;
2641 AcceptsEquality = true;
2642 ReverseOrderSLT = true;
2643 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2644 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2645 ZeroSrcOpcode = Mips::BGEZ;
2646 ZeroTrgOpcode = Mips::BLEZ;
2652 AcceptsEquality = true;
2653 ReverseOrderSLT = false;
2654 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2655 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2656 ZeroSrcOpcode = Mips::BLEZ;
2657 ZeroTrgOpcode = Mips::BGEZ;
2663 AcceptsEquality = false;
2664 ReverseOrderSLT = true;
2665 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2666 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2667 ZeroSrcOpcode = Mips::BLTZ;
2668 ZeroTrgOpcode = Mips::BGTZ;
2671 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2674 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2675 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2676 if (IsSrcRegZero && IsTrgRegZero) {
2677 // FIXME: All of these Opcode-specific if's are needed for compatibility
2678 // with GAS' behaviour. However, they may not generate the most efficient
2679 // code in some circumstances.
2680 if (PseudoOpcode == Mips::BLT) {
2681 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2685 if (PseudoOpcode == Mips::BLE) {
2686 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2688 Warning(IDLoc, "branch is always taken");
2691 if (PseudoOpcode == Mips::BGE) {
2692 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2694 Warning(IDLoc, "branch is always taken");
2697 if (PseudoOpcode == Mips::BGT) {
2698 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2702 if (PseudoOpcode == Mips::BGTU) {
2703 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2704 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2707 if (AcceptsEquality) {
2708 // If both registers are $0 and the pseudo-branch accepts equality, it
2709 // will always be taken, so we emit an unconditional branch.
2710 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2711 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2712 Warning(IDLoc, "branch is always taken");
2715 // If both registers are $0 and the pseudo-branch does not accept
2716 // equality, it will never be taken, so we don't have to emit anything.
2719 if (IsSrcRegZero || IsTrgRegZero) {
2720 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2721 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2722 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2723 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2724 // the pseudo-branch will never be taken, so we don't emit anything.
2725 // This only applies to unsigned pseudo-branches.
2728 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2729 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2730 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2731 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2732 // the pseudo-branch will always be taken, so we emit an unconditional
2734 // This only applies to unsigned pseudo-branches.
2735 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2736 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2737 Warning(IDLoc, "branch is always taken");
2741 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2742 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2743 // the pseudo-branch will be taken only when the non-zero register is
2744 // different from 0, so we emit a BNEZ.
2746 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2747 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2748 // the pseudo-branch will be taken only when the non-zero register is
2749 // equal to 0, so we emit a BEQZ.
2751 // Because only BLEU and BGEU branch on equality, we can use the
2752 // AcceptsEquality variable to decide when to emit the BEQZ.
2753 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2754 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2755 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2758 // If we have a signed pseudo-branch and one of the registers is $0,
2759 // we can use an appropriate compare-to-zero branch. We select which one
2760 // to use in the switch statement above.
2761 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2762 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2763 IDLoc, Instructions);
2767 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2768 // expansions. If it is not available, we return.
2769 unsigned ATRegNum = getATReg(IDLoc);
2773 warnIfNoMacro(IDLoc);
2775 // SLT fits well with 2 of our 4 pseudo-branches:
2776 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2777 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2778 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2779 // This is accomplished by using a BNEZ with the result of the SLT.
2781 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2782 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2783 // Because only BGE and BLE branch on equality, we can use the
2784 // AcceptsEquality variable to decide when to emit the BEQZ.
2785 // Note that the order of the SLT arguments doesn't change between
2788 // The same applies to the unsigned variants, except that SLTu is used
2790 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2791 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2792 IDLoc, Instructions);
2794 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2795 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2796 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2801 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2802 SmallVectorImpl<MCInst> &Instructions,
2803 const bool IsMips64, const bool Signed) {
2804 if (hasMips32r6()) {
2805 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2809 warnIfNoMacro(IDLoc);
2811 const MCOperand &RsRegOp = Inst.getOperand(0);
2812 assert(RsRegOp.isReg() && "expected register operand kind");
2813 unsigned RsReg = RsRegOp.getReg();
2815 const MCOperand &RtRegOp = Inst.getOperand(1);
2816 assert(RtRegOp.isReg() && "expected register operand kind");
2817 unsigned RtReg = RtRegOp.getReg();
2822 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2823 ZeroReg = Mips::ZERO_64;
2825 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2826 ZeroReg = Mips::ZERO;
2829 bool UseTraps = useTraps();
2831 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2832 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2833 Warning(IDLoc, "dividing zero by zero");
2835 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2837 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2841 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2845 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2850 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2851 Warning(IDLoc, "division by zero");
2854 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2858 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2863 // FIXME: The values for these two BranchTarget variables may be different in
2864 // micromips. These magic numbers need to be removed.
2865 unsigned BranchTargetNoTraps;
2866 unsigned BranchTarget;
2869 BranchTarget = IsMips64 ? 12 : 8;
2870 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2872 BranchTarget = IsMips64 ? 20 : 16;
2873 BranchTargetNoTraps = 8;
2874 // Branch to the li instruction.
2875 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2879 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2882 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2885 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2889 unsigned ATReg = getATReg(IDLoc);
2893 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2895 // Branch to the mflo instruction.
2896 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2897 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2898 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2900 // Branch to the mflo instruction.
2901 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2902 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2906 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2908 // Branch to the mflo instruction.
2909 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2910 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2911 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2913 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2917 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2918 SmallVectorImpl<MCInst> &Instructions) {
2919 if (hasMips32r6() || hasMips64r6()) {
2920 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2924 warnIfNoMacro(IDLoc);
2926 const MCOperand &DstRegOp = Inst.getOperand(0);
2927 assert(DstRegOp.isReg() && "expected register operand kind");
2929 const MCOperand &SrcRegOp = Inst.getOperand(1);
2930 assert(SrcRegOp.isReg() && "expected register operand kind");
2932 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2933 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2935 unsigned DstReg = DstRegOp.getReg();
2936 unsigned SrcReg = SrcRegOp.getReg();
2937 int64_t OffsetValue = OffsetImmOp.getImm();
2939 // NOTE: We always need AT for ULHU, as it is always used as the source
2940 // register for one of the LBu's.
2941 unsigned ATReg = getATReg(IDLoc);
2945 // When the value of offset+1 does not fit in 16 bits, we have to load the
2946 // offset in AT, (D)ADDu the original source register (if there was one), and
2947 // then use AT as the source register for the 2 generated LBu's.
2948 bool LoadedOffsetInAT = false;
2949 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2950 LoadedOffsetInAT = true;
2952 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2953 true, IDLoc, Instructions))
2956 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2957 // because it will make our output more similar to GAS'. For example,
2958 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2959 // instead of just an "ori $1, $9, 32768".
2960 // NOTE: If there is no source register specified in the ULHU, the parser
2961 // will interpret it as $0.
2962 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2963 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2966 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2967 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2968 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2970 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2972 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2973 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2975 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2976 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2979 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2981 emitRRI(Mips::LBu, FirstLbuDstReg, LbuSrcReg, FirstLbuOffset, IDLoc,
2984 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
2987 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
2989 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
2994 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2995 SmallVectorImpl<MCInst> &Instructions) {
2996 if (hasMips32r6() || hasMips64r6()) {
2997 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3001 const MCOperand &DstRegOp = Inst.getOperand(0);
3002 assert(DstRegOp.isReg() && "expected register operand kind");
3004 const MCOperand &SrcRegOp = Inst.getOperand(1);
3005 assert(SrcRegOp.isReg() && "expected register operand kind");
3007 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3008 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3010 unsigned SrcReg = SrcRegOp.getReg();
3011 int64_t OffsetValue = OffsetImmOp.getImm();
3014 // When the value of offset+3 does not fit in 16 bits, we have to load the
3015 // offset in AT, (D)ADDu the original source register (if there was one), and
3016 // then use AT as the source register for the generated LWL and LWR.
3017 bool LoadedOffsetInAT = false;
3018 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3019 ATReg = getATReg(IDLoc);
3022 LoadedOffsetInAT = true;
3024 warnIfNoMacro(IDLoc);
3026 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3027 true, IDLoc, Instructions))
3030 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3031 // because it will make our output more similar to GAS'. For example,
3032 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3033 // instead of just an "ori $1, $9, 32768".
3034 // NOTE: If there is no source register specified in the ULW, the parser
3035 // will interpret it as $0.
3036 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3037 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3040 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3041 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3043 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3044 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3046 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3047 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3050 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3053 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3059 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3060 SmallVectorImpl<MCInst> &Instructions) {
3062 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3063 assert (Inst.getOperand(0).isReg() &&
3064 Inst.getOperand(1).isReg() &&
3065 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3067 unsigned ATReg = Mips::NoRegister;
3068 unsigned FinalDstReg = Mips::NoRegister;
3069 unsigned DstReg = Inst.getOperand(0).getReg();
3070 unsigned SrcReg = Inst.getOperand(1).getReg();
3071 int64_t ImmValue = Inst.getOperand(2).getImm();
3073 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3075 unsigned FinalOpcode = Inst.getOpcode();
3077 if (DstReg == SrcReg) {
3078 ATReg = getATReg(Inst.getLoc());
3081 FinalDstReg = DstReg;
3085 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3086 switch (FinalOpcode) {
3088 llvm_unreachable("unimplemented expansion");
3090 FinalOpcode = Mips::ADD;
3093 FinalOpcode = Mips::ADDu;
3096 FinalOpcode = Mips::AND;
3098 case (Mips::NORImm):
3099 FinalOpcode = Mips::NOR;
3102 FinalOpcode = Mips::OR;
3105 FinalOpcode = Mips::SLT;
3108 FinalOpcode = Mips::SLTu;
3111 FinalOpcode = Mips::XOR;
3115 if (FinalDstReg == Mips::NoRegister)
3116 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3118 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3125 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3126 SmallVectorImpl<MCInst> &Instructions) {
3127 if (hasShortDelaySlot)
3128 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3130 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3133 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3134 unsigned TrgReg, bool Is64Bit,
3135 SmallVectorImpl<MCInst> &Instructions) {
3136 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3140 void MipsAsmParser::createCpRestoreMemOp(
3141 bool IsLoad, int StackOffset, SMLoc IDLoc,
3142 SmallVectorImpl<MCInst> &Instructions) {
3143 // If the offset can not fit into 16 bits, we need to expand.
3144 if (!isInt<16>(StackOffset)) {
3146 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3147 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3148 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3149 MemInst.addOperand(MCOperand::createImm(StackOffset));
3150 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3154 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3158 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3159 // As described by the Mips32r2 spec, the registers Rd and Rs for
3160 // jalr.hb must be different.
3161 unsigned Opcode = Inst.getOpcode();
3163 if (Opcode == Mips::JALR_HB &&
3164 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3165 return Match_RequiresDifferentSrcAndDst;
3167 return Match_Success;
3170 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3171 OperandVector &Operands,
3173 uint64_t &ErrorInfo,
3174 bool MatchingInlineAsm) {
3177 SmallVector<MCInst, 8> Instructions;
3178 unsigned MatchResult =
3179 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3181 switch (MatchResult) {
3182 case Match_Success: {
3183 if (processInstruction(Inst, IDLoc, Instructions))
3185 for (unsigned i = 0; i < Instructions.size(); i++)
3186 Out.EmitInstruction(Instructions[i], STI);
3189 case Match_MissingFeature:
3190 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3192 case Match_InvalidOperand: {
3193 SMLoc ErrorLoc = IDLoc;
3194 if (ErrorInfo != ~0ULL) {
3195 if (ErrorInfo >= Operands.size())
3196 return Error(IDLoc, "too few operands for instruction");
3198 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3199 if (ErrorLoc == SMLoc())
3203 return Error(ErrorLoc, "invalid operand for instruction");
3205 case Match_MnemonicFail:
3206 return Error(IDLoc, "invalid instruction");
3207 case Match_RequiresDifferentSrcAndDst:
3208 return Error(IDLoc, "source and destination must be different");
3211 llvm_unreachable("Implement any new match types added!");
3214 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3215 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3216 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3217 ") without \".set noat\"");
3220 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3221 if (!AssemblerOptions.back()->isMacro())
3222 Warning(Loc, "macro instruction expanded into multiple instructions");
3226 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3227 SMRange Range, bool ShowColors) {
3228 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3229 Range, SMFixIt(Range, FixMsg),
3233 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3236 CC = StringSwitch<unsigned>(Name)
3272 if (!(isABI_N32() || isABI_N64()))
3275 if (12 <= CC && CC <= 15) {
3276 // Name is one of t4-t7
3277 AsmToken RegTok = getLexer().peekTok();
3278 SMRange RegRange = RegTok.getLocRange();
3280 StringRef FixedName = StringSwitch<StringRef>(Name)
3286 assert(FixedName != "" && "Register name is not one of t4-t7.");
3288 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3289 "Did you mean $" + FixedName + "?", RegRange);
3292 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3293 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3294 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3295 if (8 <= CC && CC <= 11)
3299 CC = StringSwitch<unsigned>(Name)
3311 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3314 CC = StringSwitch<unsigned>(Name)
3315 .Case("hwr_cpunum", 0)
3316 .Case("hwr_synci_step", 1)
3318 .Case("hwr_ccres", 3)
3319 .Case("hwr_ulr", 29)
3325 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3327 if (Name[0] == 'f') {
3328 StringRef NumString = Name.substr(1);
3330 if (NumString.getAsInteger(10, IntVal))
3331 return -1; // This is not an integer.
3332 if (IntVal > 31) // Maximum index for fpu register.
3339 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3341 if (Name.startswith("fcc")) {
3342 StringRef NumString = Name.substr(3);
3344 if (NumString.getAsInteger(10, IntVal))
3345 return -1; // This is not an integer.
3346 if (IntVal > 7) // There are only 8 fcc registers.
3353 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3355 if (Name.startswith("ac")) {
3356 StringRef NumString = Name.substr(2);
3358 if (NumString.getAsInteger(10, IntVal))
3359 return -1; // This is not an integer.
3360 if (IntVal > 3) // There are only 3 acc registers.
3367 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3370 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3379 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3382 CC = StringSwitch<unsigned>(Name)
3385 .Case("msaaccess", 2)
3387 .Case("msamodify", 4)
3388 .Case("msarequest", 5)
3390 .Case("msaunmap", 7)
3396 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3397 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3399 reportParseError(Loc,
3400 "pseudo-instruction requires $at, which is not available");
3403 unsigned AT = getReg(
3404 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3408 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3409 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3412 unsigned MipsAsmParser::getGPR(int RegNo) {
3413 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3417 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3419 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3422 return getReg(RegClass, RegNum);
3425 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3426 MCAsmParser &Parser = getParser();
3427 DEBUG(dbgs() << "parseOperand\n");
3429 // Check if the current operand has a custom associated parser, if so, try to
3430 // custom parse the operand, or fallback to the general approach.
3431 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3432 if (ResTy == MatchOperand_Success)
3434 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3435 // there was a match, but an error occurred, in which case, just return that
3436 // the operand parsing failed.
3437 if (ResTy == MatchOperand_ParseFail)
3440 DEBUG(dbgs() << ".. Generic Parser\n");
3442 switch (getLexer().getKind()) {
3444 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3446 case AsmToken::Dollar: {
3447 // Parse the register.
3448 SMLoc S = Parser.getTok().getLoc();
3450 // Almost all registers have been parsed by custom parsers. There is only
3451 // one exception to this. $zero (and it's alias $0) will reach this point
3452 // for div, divu, and similar instructions because it is not an operand
3453 // to the instruction definition but an explicit register. Special case
3454 // this situation for now.
3455 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3458 // Maybe it is a symbol reference.
3459 StringRef Identifier;
3460 if (Parser.parseIdentifier(Identifier))
3463 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3464 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3465 // Otherwise create a symbol reference.
3467 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3469 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3472 // Else drop to expression parsing.
3473 case AsmToken::LParen:
3474 case AsmToken::Minus:
3475 case AsmToken::Plus:
3476 case AsmToken::Integer:
3477 case AsmToken::Tilde:
3478 case AsmToken::String: {
3479 DEBUG(dbgs() << ".. generic integer\n");
3480 OperandMatchResultTy ResTy = parseImm(Operands);
3481 return ResTy != MatchOperand_Success;
3483 case AsmToken::Percent: {
3484 // It is a symbol reference or constant expression.
3485 const MCExpr *IdVal;
3486 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3487 if (parseRelocOperand(IdVal))
3490 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3492 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3494 } // case AsmToken::Percent
3495 } // switch(getLexer().getKind())
3499 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3500 StringRef RelocStr) {
3502 // Check the type of the expression.
3503 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3504 // It's a constant, evaluate reloc value.
3506 switch (getVariantKind(RelocStr)) {
3507 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3508 // Get the 1st 16-bits.
3509 Val = MCE->getValue() & 0xffff;
3511 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3512 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3513 // 16 bits being negative.
3514 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3516 case MCSymbolRefExpr::VK_Mips_HIGHER:
3517 // Get the 3rd 16-bits.
3518 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3520 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3521 // Get the 4th 16-bits.
3522 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3525 report_fatal_error("unsupported reloc value");
3527 return MCConstantExpr::create(Val, getContext());
3530 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3531 // It's a symbol, create a symbolic expression from the symbol.
3532 const MCSymbol *Symbol = &MSRE->getSymbol();
3533 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3534 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3538 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3539 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3541 // Try to create target expression.
3542 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3543 return MipsMCExpr::create(VK, Expr, getContext());
3545 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3546 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3547 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3551 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3552 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3553 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3556 // Just return the original expression.
3560 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3562 switch (Expr->getKind()) {
3563 case MCExpr::Constant:
3565 case MCExpr::SymbolRef:
3566 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3567 case MCExpr::Binary:
3568 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3569 if (!isEvaluated(BE->getLHS()))
3571 return isEvaluated(BE->getRHS());
3574 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3575 case MCExpr::Target:
3581 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3582 MCAsmParser &Parser = getParser();
3583 Parser.Lex(); // Eat the % token.
3584 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3585 if (Tok.isNot(AsmToken::Identifier))
3588 std::string Str = Tok.getIdentifier();
3590 Parser.Lex(); // Eat the identifier.
3591 // Now make an expression from the rest of the operand.
3592 const MCExpr *IdVal;
3595 if (getLexer().getKind() == AsmToken::LParen) {
3597 Parser.Lex(); // Eat the '(' token.
3598 if (getLexer().getKind() == AsmToken::Percent) {
3599 Parser.Lex(); // Eat the % token.
3600 const AsmToken &nextTok = Parser.getTok();
3601 if (nextTok.isNot(AsmToken::Identifier))
3604 Str += nextTok.getIdentifier();
3605 Parser.Lex(); // Eat the identifier.
3606 if (getLexer().getKind() != AsmToken::LParen)
3611 if (getParser().parseParenExpression(IdVal, EndLoc))
3614 while (getLexer().getKind() == AsmToken::RParen)
3615 Parser.Lex(); // Eat the ')' token.
3618 return true; // Parenthesis must follow the relocation operand.
3620 Res = evaluateRelocExpr(IdVal, Str);
3624 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3626 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3627 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3628 if (ResTy == MatchOperand_Success) {
3629 assert(Operands.size() == 1);
3630 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3631 StartLoc = Operand.getStartLoc();
3632 EndLoc = Operand.getEndLoc();
3634 // AFAIK, we only support numeric registers and named GPR's in CFI
3636 // Don't worry about eating tokens before failing. Using an unrecognised
3637 // register is a parse error.
3638 if (Operand.isGPRAsmReg()) {
3639 // Resolve to GPR32 or GPR64 appropriately.
3640 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3643 return (RegNo == (unsigned)-1);
3646 assert(Operands.size() == 0);
3647 return (RegNo == (unsigned)-1);
3650 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3651 MCAsmParser &Parser = getParser();
3654 unsigned NumOfLParen = 0;
3656 while (getLexer().getKind() == AsmToken::LParen) {
3661 switch (getLexer().getKind()) {
3664 case AsmToken::Identifier:
3665 case AsmToken::LParen:
3666 case AsmToken::Integer:
3667 case AsmToken::Minus:
3668 case AsmToken::Plus:
3670 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3672 Result = (getParser().parseExpression(Res));
3673 while (getLexer().getKind() == AsmToken::RParen)
3676 case AsmToken::Percent:
3677 Result = parseRelocOperand(Res);
3682 MipsAsmParser::OperandMatchResultTy
3683 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3684 MCAsmParser &Parser = getParser();
3685 DEBUG(dbgs() << "parseMemOperand\n");
3686 const MCExpr *IdVal = nullptr;
3688 bool isParenExpr = false;
3689 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3690 // First operand is the offset.
3691 S = Parser.getTok().getLoc();
3693 if (getLexer().getKind() == AsmToken::LParen) {
3698 if (getLexer().getKind() != AsmToken::Dollar) {
3699 if (parseMemOffset(IdVal, isParenExpr))
3700 return MatchOperand_ParseFail;
3702 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3703 if (Tok.isNot(AsmToken::LParen)) {
3704 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3705 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3707 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3708 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3709 return MatchOperand_Success;
3711 if (Tok.is(AsmToken::EndOfStatement)) {
3713 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3715 // Zero register assumed, add a memory operand with ZERO as its base.
3716 // "Base" will be managed by k_Memory.
3717 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3720 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3721 return MatchOperand_Success;
3723 Error(Parser.getTok().getLoc(), "'(' expected");
3724 return MatchOperand_ParseFail;
3727 Parser.Lex(); // Eat the '(' token.
3730 Res = parseAnyRegister(Operands);
3731 if (Res != MatchOperand_Success)
3734 if (Parser.getTok().isNot(AsmToken::RParen)) {
3735 Error(Parser.getTok().getLoc(), "')' expected");
3736 return MatchOperand_ParseFail;
3739 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3741 Parser.Lex(); // Eat the ')' token.
3744 IdVal = MCConstantExpr::create(0, getContext());
3746 // Replace the register operand with the memory operand.
3747 std::unique_ptr<MipsOperand> op(
3748 static_cast<MipsOperand *>(Operands.back().release()));
3749 // Remove the register from the operands.
3750 // "op" will be managed by k_Memory.
3751 Operands.pop_back();
3752 // Add the memory operand.
3753 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3755 if (IdVal->evaluateAsAbsolute(Imm))
3756 IdVal = MCConstantExpr::create(Imm, getContext());
3757 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3758 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3762 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3763 return MatchOperand_Success;
3766 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3767 MCAsmParser &Parser = getParser();
3768 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3770 SMLoc S = Parser.getTok().getLoc();
3772 if (Sym->isVariable())
3773 Expr = Sym->getVariableValue();
3776 if (Expr->getKind() == MCExpr::SymbolRef) {
3777 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3778 StringRef DefSymbol = Ref->getSymbol().getName();
3779 if (DefSymbol.startswith("$")) {
3780 OperandMatchResultTy ResTy =
3781 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3782 if (ResTy == MatchOperand_Success) {
3785 } else if (ResTy == MatchOperand_ParseFail)
3786 llvm_unreachable("Should never ParseFail");
3789 } else if (Expr->getKind() == MCExpr::Constant) {
3791 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3793 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3800 MipsAsmParser::OperandMatchResultTy
3801 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3802 StringRef Identifier,
3804 int Index = matchCPURegisterName(Identifier);
3806 Operands.push_back(MipsOperand::createGPRReg(
3807 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3808 return MatchOperand_Success;
3811 Index = matchHWRegsRegisterName(Identifier);
3813 Operands.push_back(MipsOperand::createHWRegsReg(
3814 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3815 return MatchOperand_Success;
3818 Index = matchFPURegisterName(Identifier);
3820 Operands.push_back(MipsOperand::createFGRReg(
3821 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3822 return MatchOperand_Success;
3825 Index = matchFCCRegisterName(Identifier);
3827 Operands.push_back(MipsOperand::createFCCReg(
3828 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3829 return MatchOperand_Success;
3832 Index = matchACRegisterName(Identifier);
3834 Operands.push_back(MipsOperand::createACCReg(
3835 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3836 return MatchOperand_Success;
3839 Index = matchMSA128RegisterName(Identifier);
3841 Operands.push_back(MipsOperand::createMSA128Reg(
3842 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3843 return MatchOperand_Success;
3846 Index = matchMSA128CtrlRegisterName(Identifier);
3848 Operands.push_back(MipsOperand::createMSACtrlReg(
3849 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3850 return MatchOperand_Success;
3853 return MatchOperand_NoMatch;
3856 MipsAsmParser::OperandMatchResultTy
3857 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3858 MCAsmParser &Parser = getParser();
3859 auto Token = Parser.getLexer().peekTok(false);
3861 if (Token.is(AsmToken::Identifier)) {
3862 DEBUG(dbgs() << ".. identifier\n");
3863 StringRef Identifier = Token.getIdentifier();
3864 OperandMatchResultTy ResTy =
3865 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3867 } else if (Token.is(AsmToken::Integer)) {
3868 DEBUG(dbgs() << ".. integer\n");
3869 Operands.push_back(MipsOperand::createNumericReg(
3870 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3872 return MatchOperand_Success;
3875 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3877 return MatchOperand_NoMatch;
3880 MipsAsmParser::OperandMatchResultTy
3881 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3882 MCAsmParser &Parser = getParser();
3883 DEBUG(dbgs() << "parseAnyRegister\n");
3885 auto Token = Parser.getTok();
3887 SMLoc S = Token.getLoc();
3889 if (Token.isNot(AsmToken::Dollar)) {
3890 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3891 if (Token.is(AsmToken::Identifier)) {
3892 if (searchSymbolAlias(Operands))
3893 return MatchOperand_Success;
3895 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3896 return MatchOperand_NoMatch;
3898 DEBUG(dbgs() << ".. $\n");
3900 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3901 if (ResTy == MatchOperand_Success) {
3903 Parser.Lex(); // identifier
3908 MipsAsmParser::OperandMatchResultTy
3909 MipsAsmParser::parseImm(OperandVector &Operands) {
3910 MCAsmParser &Parser = getParser();
3911 switch (getLexer().getKind()) {
3913 return MatchOperand_NoMatch;
3914 case AsmToken::LParen:
3915 case AsmToken::Minus:
3916 case AsmToken::Plus:
3917 case AsmToken::Integer:
3918 case AsmToken::Tilde:
3919 case AsmToken::String:
3923 const MCExpr *IdVal;
3924 SMLoc S = Parser.getTok().getLoc();
3925 if (getParser().parseExpression(IdVal))
3926 return MatchOperand_ParseFail;
3928 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3929 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3930 return MatchOperand_Success;
3933 MipsAsmParser::OperandMatchResultTy
3934 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3935 MCAsmParser &Parser = getParser();
3936 DEBUG(dbgs() << "parseJumpTarget\n");
3938 SMLoc S = getLexer().getLoc();
3940 // Integers and expressions are acceptable
3941 OperandMatchResultTy ResTy = parseImm(Operands);
3942 if (ResTy != MatchOperand_NoMatch)
3945 // Registers are a valid target and have priority over symbols.
3946 ResTy = parseAnyRegister(Operands);
3947 if (ResTy != MatchOperand_NoMatch)
3950 const MCExpr *Expr = nullptr;
3951 if (Parser.parseExpression(Expr)) {
3952 // We have no way of knowing if a symbol was consumed so we must ParseFail
3953 return MatchOperand_ParseFail;
3956 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3957 return MatchOperand_Success;
3960 MipsAsmParser::OperandMatchResultTy
3961 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3962 MCAsmParser &Parser = getParser();
3963 const MCExpr *IdVal;
3964 // If the first token is '$' we may have register operand.
3965 if (Parser.getTok().is(AsmToken::Dollar))
3966 return MatchOperand_NoMatch;
3967 SMLoc S = Parser.getTok().getLoc();
3968 if (getParser().parseExpression(IdVal))
3969 return MatchOperand_ParseFail;
3970 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3971 assert(MCE && "Unexpected MCExpr type.");
3972 int64_t Val = MCE->getValue();
3973 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3974 Operands.push_back(MipsOperand::CreateImm(
3975 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3976 return MatchOperand_Success;
3979 MipsAsmParser::OperandMatchResultTy
3980 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3981 MCAsmParser &Parser = getParser();
3982 switch (getLexer().getKind()) {
3984 return MatchOperand_NoMatch;
3985 case AsmToken::LParen:
3986 case AsmToken::Plus:
3987 case AsmToken::Minus:
3988 case AsmToken::Integer:
3993 SMLoc S = Parser.getTok().getLoc();
3995 if (getParser().parseExpression(Expr))
3996 return MatchOperand_ParseFail;
3999 if (!Expr->evaluateAsAbsolute(Val)) {
4000 Error(S, "expected immediate value");
4001 return MatchOperand_ParseFail;
4004 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4005 // and because the CPU always adds one to the immediate field, the allowed
4006 // range becomes 1..4. We'll only check the range here and will deal
4007 // with the addition/subtraction when actually decoding/encoding
4009 if (Val < 1 || Val > 4) {
4010 Error(S, "immediate not in range (1..4)");
4011 return MatchOperand_ParseFail;
4015 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4016 return MatchOperand_Success;
4019 MipsAsmParser::OperandMatchResultTy
4020 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4021 MCAsmParser &Parser = getParser();
4022 SmallVector<unsigned, 10> Regs;
4024 unsigned PrevReg = Mips::NoRegister;
4025 bool RegRange = false;
4026 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4028 if (Parser.getTok().isNot(AsmToken::Dollar))
4029 return MatchOperand_ParseFail;
4031 SMLoc S = Parser.getTok().getLoc();
4032 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4033 SMLoc E = getLexer().getLoc();
4034 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4035 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4037 // Remove last register operand because registers from register range
4038 // should be inserted first.
4039 if (RegNo == Mips::RA) {
4040 Regs.push_back(RegNo);
4042 unsigned TmpReg = PrevReg + 1;
4043 while (TmpReg <= RegNo) {
4044 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4045 Error(E, "invalid register operand");
4046 return MatchOperand_ParseFail;
4050 Regs.push_back(TmpReg++);
4056 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4057 (RegNo != Mips::RA)) {
4058 Error(E, "$16 or $31 expected");
4059 return MatchOperand_ParseFail;
4060 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4061 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4062 Error(E, "invalid register operand");
4063 return MatchOperand_ParseFail;
4064 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4065 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4066 Error(E, "consecutive register numbers expected");
4067 return MatchOperand_ParseFail;
4070 Regs.push_back(RegNo);
4073 if (Parser.getTok().is(AsmToken::Minus))
4076 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4077 !Parser.getTok().isNot(AsmToken::Comma)) {
4078 Error(E, "',' or '-' expected");
4079 return MatchOperand_ParseFail;
4082 Lex(); // Consume comma or minus
4083 if (Parser.getTok().isNot(AsmToken::Dollar))
4089 SMLoc E = Parser.getTok().getLoc();
4090 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4091 parseMemOperand(Operands);
4092 return MatchOperand_Success;
4095 MipsAsmParser::OperandMatchResultTy
4096 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4097 MCAsmParser &Parser = getParser();
4099 SMLoc S = Parser.getTok().getLoc();
4100 if (parseAnyRegister(Operands) != MatchOperand_Success)
4101 return MatchOperand_ParseFail;
4103 SMLoc E = Parser.getTok().getLoc();
4104 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4105 unsigned Reg = Op.getGPR32Reg();
4106 Operands.pop_back();
4107 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4108 return MatchOperand_Success;
4111 MipsAsmParser::OperandMatchResultTy
4112 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4113 MCAsmParser &Parser = getParser();
4114 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4115 SmallVector<unsigned, 10> Regs;
4117 if (Parser.getTok().isNot(AsmToken::Dollar))
4118 return MatchOperand_ParseFail;
4120 SMLoc S = Parser.getTok().getLoc();
4122 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4123 return MatchOperand_ParseFail;
4125 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4126 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4127 Regs.push_back(RegNo);
4129 SMLoc E = Parser.getTok().getLoc();
4130 if (Parser.getTok().isNot(AsmToken::Comma)) {
4131 Error(E, "',' expected");
4132 return MatchOperand_ParseFail;
4138 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4139 return MatchOperand_ParseFail;
4141 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4142 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4143 Regs.push_back(RegNo);
4145 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4147 return MatchOperand_Success;
4150 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4152 MCSymbolRefExpr::VariantKind VK =
4153 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4154 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4155 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4156 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4157 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4158 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4159 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4160 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4161 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4162 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4163 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4164 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4165 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4166 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4167 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4168 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4169 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4170 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4171 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4172 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4173 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4174 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4175 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4176 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4177 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4178 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4179 .Default(MCSymbolRefExpr::VK_None);
4181 assert(VK != MCSymbolRefExpr::VK_None);
4186 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4188 /// ::= '(', register, ')'
4189 /// handle it before we iterate so we don't get tripped up by the lack of
4191 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4192 MCAsmParser &Parser = getParser();
4193 if (getLexer().is(AsmToken::LParen)) {
4195 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4197 if (parseOperand(Operands, Name)) {
4198 SMLoc Loc = getLexer().getLoc();
4199 Parser.eatToEndOfStatement();
4200 return Error(Loc, "unexpected token in argument list");
4202 if (Parser.getTok().isNot(AsmToken::RParen)) {
4203 SMLoc Loc = getLexer().getLoc();
4204 Parser.eatToEndOfStatement();
4205 return Error(Loc, "unexpected token, expected ')'");
4208 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4214 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4215 /// either one of these.
4216 /// ::= '[', register, ']'
4217 /// ::= '[', integer, ']'
4218 /// handle it before we iterate so we don't get tripped up by the lack of
4220 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4221 OperandVector &Operands) {
4222 MCAsmParser &Parser = getParser();
4223 if (getLexer().is(AsmToken::LBrac)) {
4225 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4227 if (parseOperand(Operands, Name)) {
4228 SMLoc Loc = getLexer().getLoc();
4229 Parser.eatToEndOfStatement();
4230 return Error(Loc, "unexpected token in argument list");
4232 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4233 SMLoc Loc = getLexer().getLoc();
4234 Parser.eatToEndOfStatement();
4235 return Error(Loc, "unexpected token, expected ']'");
4238 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4244 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4245 SMLoc NameLoc, OperandVector &Operands) {
4246 MCAsmParser &Parser = getParser();
4247 DEBUG(dbgs() << "ParseInstruction\n");
4249 // We have reached first instruction, module directive are now forbidden.
4250 getTargetStreamer().forbidModuleDirective();
4252 // Check if we have valid mnemonic
4253 if (!mnemonicIsValid(Name, 0)) {
4254 Parser.eatToEndOfStatement();
4255 return Error(NameLoc, "unknown instruction");
4257 // First operand in MCInst is instruction mnemonic.
4258 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4260 // Read the remaining operands.
4261 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4262 // Read the first operand.
4263 if (parseOperand(Operands, Name)) {
4264 SMLoc Loc = getLexer().getLoc();
4265 Parser.eatToEndOfStatement();
4266 return Error(Loc, "unexpected token in argument list");
4268 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4270 // AFAIK, parenthesis suffixes are never on the first operand
4272 while (getLexer().is(AsmToken::Comma)) {
4273 Parser.Lex(); // Eat the comma.
4274 // Parse and remember the operand.
4275 if (parseOperand(Operands, Name)) {
4276 SMLoc Loc = getLexer().getLoc();
4277 Parser.eatToEndOfStatement();
4278 return Error(Loc, "unexpected token in argument list");
4280 // Parse bracket and parenthesis suffixes before we iterate
4281 if (getLexer().is(AsmToken::LBrac)) {
4282 if (parseBracketSuffix(Name, Operands))
4284 } else if (getLexer().is(AsmToken::LParen) &&
4285 parseParenSuffix(Name, Operands))
4289 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4290 SMLoc Loc = getLexer().getLoc();
4291 Parser.eatToEndOfStatement();
4292 return Error(Loc, "unexpected token in argument list");
4294 Parser.Lex(); // Consume the EndOfStatement.
4298 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4299 MCAsmParser &Parser = getParser();
4300 SMLoc Loc = getLexer().getLoc();
4301 Parser.eatToEndOfStatement();
4302 return Error(Loc, ErrorMsg);
4305 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4306 return Error(Loc, ErrorMsg);
4309 bool MipsAsmParser::parseSetNoAtDirective() {
4310 MCAsmParser &Parser = getParser();
4311 // Line should look like: ".set noat".
4313 // Set the $at register to $0.
4314 AssemblerOptions.back()->setATRegIndex(0);
4316 Parser.Lex(); // Eat "noat".
4318 // If this is not the end of the statement, report an error.
4319 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4320 reportParseError("unexpected token, expected end of statement");
4324 getTargetStreamer().emitDirectiveSetNoAt();
4325 Parser.Lex(); // Consume the EndOfStatement.
4329 bool MipsAsmParser::parseSetAtDirective() {
4330 // Line can be: ".set at", which sets $at to $1
4331 // or ".set at=$reg", which sets $at to $reg.
4332 MCAsmParser &Parser = getParser();
4333 Parser.Lex(); // Eat "at".
4335 if (getLexer().is(AsmToken::EndOfStatement)) {
4336 // No register was specified, so we set $at to $1.
4337 AssemblerOptions.back()->setATRegIndex(1);
4339 getTargetStreamer().emitDirectiveSetAt();
4340 Parser.Lex(); // Consume the EndOfStatement.
4344 if (getLexer().isNot(AsmToken::Equal)) {
4345 reportParseError("unexpected token, expected equals sign");
4348 Parser.Lex(); // Eat "=".
4350 if (getLexer().isNot(AsmToken::Dollar)) {
4351 if (getLexer().is(AsmToken::EndOfStatement)) {
4352 reportParseError("no register specified");
4355 reportParseError("unexpected token, expected dollar sign '$'");
4359 Parser.Lex(); // Eat "$".
4361 // Find out what "reg" is.
4363 const AsmToken &Reg = Parser.getTok();
4364 if (Reg.is(AsmToken::Identifier)) {
4365 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4366 } else if (Reg.is(AsmToken::Integer)) {
4367 AtRegNo = Reg.getIntVal();
4369 reportParseError("unexpected token, expected identifier or integer");
4373 // Check if $reg is a valid register. If it is, set $at to $reg.
4374 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4375 reportParseError("invalid register");
4378 Parser.Lex(); // Eat "reg".
4380 // If this is not the end of the statement, report an error.
4381 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4382 reportParseError("unexpected token, expected end of statement");
4386 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4388 Parser.Lex(); // Consume the EndOfStatement.
4392 bool MipsAsmParser::parseSetReorderDirective() {
4393 MCAsmParser &Parser = getParser();
4395 // If this is not the end of the statement, report an error.
4396 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4397 reportParseError("unexpected token, expected end of statement");
4400 AssemblerOptions.back()->setReorder();
4401 getTargetStreamer().emitDirectiveSetReorder();
4402 Parser.Lex(); // Consume the EndOfStatement.
4406 bool MipsAsmParser::parseSetNoReorderDirective() {
4407 MCAsmParser &Parser = getParser();
4409 // If this is not the end of the statement, report an error.
4410 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4411 reportParseError("unexpected token, expected end of statement");
4414 AssemblerOptions.back()->setNoReorder();
4415 getTargetStreamer().emitDirectiveSetNoReorder();
4416 Parser.Lex(); // Consume the EndOfStatement.
4420 bool MipsAsmParser::parseSetMacroDirective() {
4421 MCAsmParser &Parser = getParser();
4423 // If this is not the end of the statement, report an error.
4424 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4425 reportParseError("unexpected token, expected end of statement");
4428 AssemblerOptions.back()->setMacro();
4429 getTargetStreamer().emitDirectiveSetMacro();
4430 Parser.Lex(); // Consume the EndOfStatement.
4434 bool MipsAsmParser::parseSetNoMacroDirective() {
4435 MCAsmParser &Parser = getParser();
4437 // If this is not the end of the statement, report an error.
4438 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4439 reportParseError("unexpected token, expected end of statement");
4442 if (AssemblerOptions.back()->isReorder()) {
4443 reportParseError("`noreorder' must be set before `nomacro'");
4446 AssemblerOptions.back()->setNoMacro();
4447 getTargetStreamer().emitDirectiveSetNoMacro();
4448 Parser.Lex(); // Consume the EndOfStatement.
4452 bool MipsAsmParser::parseSetMsaDirective() {
4453 MCAsmParser &Parser = getParser();
4456 // If this is not the end of the statement, report an error.
4457 if (getLexer().isNot(AsmToken::EndOfStatement))
4458 return reportParseError("unexpected token, expected end of statement");
4460 setFeatureBits(Mips::FeatureMSA, "msa");
4461 getTargetStreamer().emitDirectiveSetMsa();
4465 bool MipsAsmParser::parseSetNoMsaDirective() {
4466 MCAsmParser &Parser = getParser();
4469 // If this is not the end of the statement, report an error.
4470 if (getLexer().isNot(AsmToken::EndOfStatement))
4471 return reportParseError("unexpected token, expected end of statement");
4473 clearFeatureBits(Mips::FeatureMSA, "msa");
4474 getTargetStreamer().emitDirectiveSetNoMsa();
4478 bool MipsAsmParser::parseSetNoDspDirective() {
4479 MCAsmParser &Parser = getParser();
4480 Parser.Lex(); // Eat "nodsp".
4482 // If this is not the end of the statement, report an error.
4483 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4484 reportParseError("unexpected token, expected end of statement");
4488 clearFeatureBits(Mips::FeatureDSP, "dsp");
4489 getTargetStreamer().emitDirectiveSetNoDsp();
4493 bool MipsAsmParser::parseSetMips16Directive() {
4494 MCAsmParser &Parser = getParser();
4495 Parser.Lex(); // Eat "mips16".
4497 // If this is not the end of the statement, report an error.
4498 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4499 reportParseError("unexpected token, expected end of statement");
4503 setFeatureBits(Mips::FeatureMips16, "mips16");
4504 getTargetStreamer().emitDirectiveSetMips16();
4505 Parser.Lex(); // Consume the EndOfStatement.
4509 bool MipsAsmParser::parseSetNoMips16Directive() {
4510 MCAsmParser &Parser = getParser();
4511 Parser.Lex(); // Eat "nomips16".
4513 // If this is not the end of the statement, report an error.
4514 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4515 reportParseError("unexpected token, expected end of statement");
4519 clearFeatureBits(Mips::FeatureMips16, "mips16");
4520 getTargetStreamer().emitDirectiveSetNoMips16();
4521 Parser.Lex(); // Consume the EndOfStatement.
4525 bool MipsAsmParser::parseSetFpDirective() {
4526 MCAsmParser &Parser = getParser();
4527 MipsABIFlagsSection::FpABIKind FpAbiVal;
4528 // Line can be: .set fp=32
4531 Parser.Lex(); // Eat fp token
4532 AsmToken Tok = Parser.getTok();
4533 if (Tok.isNot(AsmToken::Equal)) {
4534 reportParseError("unexpected token, expected equals sign '='");
4537 Parser.Lex(); // Eat '=' token.
4538 Tok = Parser.getTok();
4540 if (!parseFpABIValue(FpAbiVal, ".set"))
4543 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4544 reportParseError("unexpected token, expected end of statement");
4547 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4548 Parser.Lex(); // Consume the EndOfStatement.
4552 bool MipsAsmParser::parseSetOddSPRegDirective() {
4553 MCAsmParser &Parser = getParser();
4555 Parser.Lex(); // Eat "oddspreg".
4556 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4557 reportParseError("unexpected token, expected end of statement");
4561 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4562 getTargetStreamer().emitDirectiveSetOddSPReg();
4566 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4567 MCAsmParser &Parser = getParser();
4569 Parser.Lex(); // Eat "nooddspreg".
4570 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4571 reportParseError("unexpected token, expected end of statement");
4575 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4576 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4580 bool MipsAsmParser::parseSetPopDirective() {
4581 MCAsmParser &Parser = getParser();
4582 SMLoc Loc = getLexer().getLoc();
4585 if (getLexer().isNot(AsmToken::EndOfStatement))
4586 return reportParseError("unexpected token, expected end of statement");
4588 // Always keep an element on the options "stack" to prevent the user
4589 // from changing the initial options. This is how we remember them.
4590 if (AssemblerOptions.size() == 2)
4591 return reportParseError(Loc, ".set pop with no .set push");
4593 AssemblerOptions.pop_back();
4594 setAvailableFeatures(
4595 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4596 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4598 getTargetStreamer().emitDirectiveSetPop();
4602 bool MipsAsmParser::parseSetPushDirective() {
4603 MCAsmParser &Parser = getParser();
4605 if (getLexer().isNot(AsmToken::EndOfStatement))
4606 return reportParseError("unexpected token, expected end of statement");
4608 // Create a copy of the current assembler options environment and push it.
4609 AssemblerOptions.push_back(
4610 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4612 getTargetStreamer().emitDirectiveSetPush();
4616 bool MipsAsmParser::parseSetSoftFloatDirective() {
4617 MCAsmParser &Parser = getParser();
4619 if (getLexer().isNot(AsmToken::EndOfStatement))
4620 return reportParseError("unexpected token, expected end of statement");
4622 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4623 getTargetStreamer().emitDirectiveSetSoftFloat();
4627 bool MipsAsmParser::parseSetHardFloatDirective() {
4628 MCAsmParser &Parser = getParser();
4630 if (getLexer().isNot(AsmToken::EndOfStatement))
4631 return reportParseError("unexpected token, expected end of statement");
4633 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4634 getTargetStreamer().emitDirectiveSetHardFloat();
4638 bool MipsAsmParser::parseSetAssignment() {
4640 const MCExpr *Value;
4641 MCAsmParser &Parser = getParser();
4643 if (Parser.parseIdentifier(Name))
4644 reportParseError("expected identifier after .set");
4646 if (getLexer().isNot(AsmToken::Comma))
4647 return reportParseError("unexpected token, expected comma");
4650 if (Parser.parseExpression(Value))
4651 return reportParseError("expected valid expression after comma");
4653 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4654 Sym->setVariableValue(Value);
4659 bool MipsAsmParser::parseSetMips0Directive() {
4660 MCAsmParser &Parser = getParser();
4662 if (getLexer().isNot(AsmToken::EndOfStatement))
4663 return reportParseError("unexpected token, expected end of statement");
4665 // Reset assembler options to their initial values.
4666 setAvailableFeatures(
4667 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4668 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4669 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4671 getTargetStreamer().emitDirectiveSetMips0();
4675 bool MipsAsmParser::parseSetArchDirective() {
4676 MCAsmParser &Parser = getParser();
4678 if (getLexer().isNot(AsmToken::Equal))
4679 return reportParseError("unexpected token, expected equals sign");
4683 if (Parser.parseIdentifier(Arch))
4684 return reportParseError("expected arch identifier");
4686 StringRef ArchFeatureName =
4687 StringSwitch<StringRef>(Arch)
4688 .Case("mips1", "mips1")
4689 .Case("mips2", "mips2")
4690 .Case("mips3", "mips3")
4691 .Case("mips4", "mips4")
4692 .Case("mips5", "mips5")
4693 .Case("mips32", "mips32")
4694 .Case("mips32r2", "mips32r2")
4695 .Case("mips32r3", "mips32r3")
4696 .Case("mips32r5", "mips32r5")
4697 .Case("mips32r6", "mips32r6")
4698 .Case("mips64", "mips64")
4699 .Case("mips64r2", "mips64r2")
4700 .Case("mips64r3", "mips64r3")
4701 .Case("mips64r5", "mips64r5")
4702 .Case("mips64r6", "mips64r6")
4703 .Case("cnmips", "cnmips")
4704 .Case("r4000", "mips3") // This is an implementation of Mips3.
4707 if (ArchFeatureName.empty())
4708 return reportParseError("unsupported architecture");
4710 selectArch(ArchFeatureName);
4711 getTargetStreamer().emitDirectiveSetArch(Arch);
4715 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4716 MCAsmParser &Parser = getParser();
4718 if (getLexer().isNot(AsmToken::EndOfStatement))
4719 return reportParseError("unexpected token, expected end of statement");
4723 llvm_unreachable("Unimplemented feature");
4724 case Mips::FeatureDSP:
4725 setFeatureBits(Mips::FeatureDSP, "dsp");
4726 getTargetStreamer().emitDirectiveSetDsp();
4728 case Mips::FeatureMicroMips:
4729 getTargetStreamer().emitDirectiveSetMicroMips();
4731 case Mips::FeatureMips1:
4732 selectArch("mips1");
4733 getTargetStreamer().emitDirectiveSetMips1();
4735 case Mips::FeatureMips2:
4736 selectArch("mips2");
4737 getTargetStreamer().emitDirectiveSetMips2();
4739 case Mips::FeatureMips3:
4740 selectArch("mips3");
4741 getTargetStreamer().emitDirectiveSetMips3();
4743 case Mips::FeatureMips4:
4744 selectArch("mips4");
4745 getTargetStreamer().emitDirectiveSetMips4();
4747 case Mips::FeatureMips5:
4748 selectArch("mips5");
4749 getTargetStreamer().emitDirectiveSetMips5();
4751 case Mips::FeatureMips32:
4752 selectArch("mips32");
4753 getTargetStreamer().emitDirectiveSetMips32();
4755 case Mips::FeatureMips32r2:
4756 selectArch("mips32r2");
4757 getTargetStreamer().emitDirectiveSetMips32R2();
4759 case Mips::FeatureMips32r3:
4760 selectArch("mips32r3");
4761 getTargetStreamer().emitDirectiveSetMips32R3();
4763 case Mips::FeatureMips32r5:
4764 selectArch("mips32r5");
4765 getTargetStreamer().emitDirectiveSetMips32R5();
4767 case Mips::FeatureMips32r6:
4768 selectArch("mips32r6");
4769 getTargetStreamer().emitDirectiveSetMips32R6();
4771 case Mips::FeatureMips64:
4772 selectArch("mips64");
4773 getTargetStreamer().emitDirectiveSetMips64();
4775 case Mips::FeatureMips64r2:
4776 selectArch("mips64r2");
4777 getTargetStreamer().emitDirectiveSetMips64R2();
4779 case Mips::FeatureMips64r3:
4780 selectArch("mips64r3");
4781 getTargetStreamer().emitDirectiveSetMips64R3();
4783 case Mips::FeatureMips64r5:
4784 selectArch("mips64r5");
4785 getTargetStreamer().emitDirectiveSetMips64R5();
4787 case Mips::FeatureMips64r6:
4788 selectArch("mips64r6");
4789 getTargetStreamer().emitDirectiveSetMips64R6();
4795 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4796 MCAsmParser &Parser = getParser();
4797 if (getLexer().isNot(AsmToken::Comma)) {
4798 SMLoc Loc = getLexer().getLoc();
4799 Parser.eatToEndOfStatement();
4800 return Error(Loc, ErrorStr);
4803 Parser.Lex(); // Eat the comma.
4807 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4808 // In this class, it is only used for .cprestore.
4809 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4810 // MipsTargetELFStreamer and MipsAsmParser.
4811 bool MipsAsmParser::isPicAndNotNxxAbi() {
4812 return inPicMode() && !(isABI_N32() || isABI_N64());
4815 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4816 if (AssemblerOptions.back()->isReorder())
4817 Warning(Loc, ".cpload should be inside a noreorder section");
4819 if (inMips16Mode()) {
4820 reportParseError(".cpload is not supported in Mips16 mode");
4824 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4825 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4826 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4827 reportParseError("expected register containing function address");
4831 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4832 if (!RegOpnd.isGPRAsmReg()) {
4833 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4837 // If this is not the end of the statement, report an error.
4838 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4839 reportParseError("unexpected token, expected end of statement");
4843 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4847 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4848 MCAsmParser &Parser = getParser();
4850 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4851 // is used in non-PIC mode.
4853 if (inMips16Mode()) {
4854 reportParseError(".cprestore is not supported in Mips16 mode");
4858 // Get the stack offset value.
4859 const MCExpr *StackOffset;
4860 int64_t StackOffsetVal;
4861 if (Parser.parseExpression(StackOffset)) {
4862 reportParseError("expected stack offset value");
4866 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4867 reportParseError("stack offset is not an absolute expression");
4871 if (StackOffsetVal < 0) {
4872 Warning(Loc, ".cprestore with negative stack offset has no effect");
4873 IsCpRestoreSet = false;
4875 IsCpRestoreSet = true;
4876 CpRestoreOffset = StackOffsetVal;
4879 // If this is not the end of the statement, report an error.
4880 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4881 reportParseError("unexpected token, expected end of statement");
4885 // Store the $gp on the stack.
4886 SmallVector<MCInst, 3> StoreInsts;
4887 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
4890 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
4891 Parser.Lex(); // Consume the EndOfStatement.
4895 bool MipsAsmParser::parseDirectiveCPSetup() {
4896 MCAsmParser &Parser = getParser();
4899 bool SaveIsReg = true;
4901 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4902 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4903 if (ResTy == MatchOperand_NoMatch) {
4904 reportParseError("expected register containing function address");
4905 Parser.eatToEndOfStatement();
4909 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4910 if (!FuncRegOpnd.isGPRAsmReg()) {
4911 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4912 Parser.eatToEndOfStatement();
4916 FuncReg = FuncRegOpnd.getGPR32Reg();
4919 if (!eatComma("unexpected token, expected comma"))
4922 ResTy = parseAnyRegister(TmpReg);
4923 if (ResTy == MatchOperand_NoMatch) {
4924 const MCExpr *OffsetExpr;
4926 SMLoc ExprLoc = getLexer().getLoc();
4928 if (Parser.parseExpression(OffsetExpr) ||
4929 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
4930 reportParseError(ExprLoc, "expected save register or stack offset");
4931 Parser.eatToEndOfStatement();
4938 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4939 if (!SaveOpnd.isGPRAsmReg()) {
4940 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4941 Parser.eatToEndOfStatement();
4944 Save = SaveOpnd.getGPR32Reg();
4947 if (!eatComma("unexpected token, expected comma"))
4951 if (Parser.parseExpression(Expr)) {
4952 reportParseError("expected expression");
4956 if (Expr->getKind() != MCExpr::SymbolRef) {
4957 reportParseError("expected symbol");
4960 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4962 CpSaveLocation = Save;
4963 CpSaveLocationIsRegister = SaveIsReg;
4965 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4970 bool MipsAsmParser::parseDirectiveCPReturn() {
4971 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
4972 CpSaveLocationIsRegister);
4976 bool MipsAsmParser::parseDirectiveNaN() {
4977 MCAsmParser &Parser = getParser();
4978 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4979 const AsmToken &Tok = Parser.getTok();
4981 if (Tok.getString() == "2008") {
4983 getTargetStreamer().emitDirectiveNaN2008();
4985 } else if (Tok.getString() == "legacy") {
4987 getTargetStreamer().emitDirectiveNaNLegacy();
4991 // If we don't recognize the option passed to the .nan
4992 // directive (e.g. no option or unknown option), emit an error.
4993 reportParseError("invalid option in .nan directive");
4997 bool MipsAsmParser::parseDirectiveSet() {
4998 MCAsmParser &Parser = getParser();
4999 // Get the next token.
5000 const AsmToken &Tok = Parser.getTok();
5002 if (Tok.getString() == "noat") {
5003 return parseSetNoAtDirective();
5004 } else if (Tok.getString() == "at") {
5005 return parseSetAtDirective();
5006 } else if (Tok.getString() == "arch") {
5007 return parseSetArchDirective();
5008 } else if (Tok.getString() == "fp") {
5009 return parseSetFpDirective();
5010 } else if (Tok.getString() == "oddspreg") {
5011 return parseSetOddSPRegDirective();
5012 } else if (Tok.getString() == "nooddspreg") {
5013 return parseSetNoOddSPRegDirective();
5014 } else if (Tok.getString() == "pop") {
5015 return parseSetPopDirective();
5016 } else if (Tok.getString() == "push") {
5017 return parseSetPushDirective();
5018 } else if (Tok.getString() == "reorder") {
5019 return parseSetReorderDirective();
5020 } else if (Tok.getString() == "noreorder") {
5021 return parseSetNoReorderDirective();
5022 } else if (Tok.getString() == "macro") {
5023 return parseSetMacroDirective();
5024 } else if (Tok.getString() == "nomacro") {
5025 return parseSetNoMacroDirective();
5026 } else if (Tok.getString() == "mips16") {
5027 return parseSetMips16Directive();
5028 } else if (Tok.getString() == "nomips16") {
5029 return parseSetNoMips16Directive();
5030 } else if (Tok.getString() == "nomicromips") {
5031 getTargetStreamer().emitDirectiveSetNoMicroMips();
5032 Parser.eatToEndOfStatement();
5034 } else if (Tok.getString() == "micromips") {
5035 return parseSetFeature(Mips::FeatureMicroMips);
5036 } else if (Tok.getString() == "mips0") {
5037 return parseSetMips0Directive();
5038 } else if (Tok.getString() == "mips1") {
5039 return parseSetFeature(Mips::FeatureMips1);
5040 } else if (Tok.getString() == "mips2") {
5041 return parseSetFeature(Mips::FeatureMips2);
5042 } else if (Tok.getString() == "mips3") {
5043 return parseSetFeature(Mips::FeatureMips3);
5044 } else if (Tok.getString() == "mips4") {
5045 return parseSetFeature(Mips::FeatureMips4);
5046 } else if (Tok.getString() == "mips5") {
5047 return parseSetFeature(Mips::FeatureMips5);
5048 } else if (Tok.getString() == "mips32") {
5049 return parseSetFeature(Mips::FeatureMips32);
5050 } else if (Tok.getString() == "mips32r2") {
5051 return parseSetFeature(Mips::FeatureMips32r2);
5052 } else if (Tok.getString() == "mips32r3") {
5053 return parseSetFeature(Mips::FeatureMips32r3);
5054 } else if (Tok.getString() == "mips32r5") {
5055 return parseSetFeature(Mips::FeatureMips32r5);
5056 } else if (Tok.getString() == "mips32r6") {
5057 return parseSetFeature(Mips::FeatureMips32r6);
5058 } else if (Tok.getString() == "mips64") {
5059 return parseSetFeature(Mips::FeatureMips64);
5060 } else if (Tok.getString() == "mips64r2") {
5061 return parseSetFeature(Mips::FeatureMips64r2);
5062 } else if (Tok.getString() == "mips64r3") {
5063 return parseSetFeature(Mips::FeatureMips64r3);
5064 } else if (Tok.getString() == "mips64r5") {
5065 return parseSetFeature(Mips::FeatureMips64r5);
5066 } else if (Tok.getString() == "mips64r6") {
5067 return parseSetFeature(Mips::FeatureMips64r6);
5068 } else if (Tok.getString() == "dsp") {
5069 return parseSetFeature(Mips::FeatureDSP);
5070 } else if (Tok.getString() == "nodsp") {
5071 return parseSetNoDspDirective();
5072 } else if (Tok.getString() == "msa") {
5073 return parseSetMsaDirective();
5074 } else if (Tok.getString() == "nomsa") {
5075 return parseSetNoMsaDirective();
5076 } else if (Tok.getString() == "softfloat") {
5077 return parseSetSoftFloatDirective();
5078 } else if (Tok.getString() == "hardfloat") {
5079 return parseSetHardFloatDirective();
5081 // It is just an identifier, look for an assignment.
5082 parseSetAssignment();
5089 /// parseDataDirective
5090 /// ::= .word [ expression (, expression)* ]
5091 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5092 MCAsmParser &Parser = getParser();
5093 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5095 const MCExpr *Value;
5096 if (getParser().parseExpression(Value))
5099 getParser().getStreamer().EmitValue(Value, Size);
5101 if (getLexer().is(AsmToken::EndOfStatement))
5104 if (getLexer().isNot(AsmToken::Comma))
5105 return Error(L, "unexpected token, expected comma");
5114 /// parseDirectiveGpWord
5115 /// ::= .gpword local_sym
5116 bool MipsAsmParser::parseDirectiveGpWord() {
5117 MCAsmParser &Parser = getParser();
5118 const MCExpr *Value;
5119 // EmitGPRel32Value requires an expression, so we are using base class
5120 // method to evaluate the expression.
5121 if (getParser().parseExpression(Value))
5123 getParser().getStreamer().EmitGPRel32Value(Value);
5125 if (getLexer().isNot(AsmToken::EndOfStatement))
5126 return Error(getLexer().getLoc(),
5127 "unexpected token, expected end of statement");
5128 Parser.Lex(); // Eat EndOfStatement token.
5132 /// parseDirectiveGpDWord
5133 /// ::= .gpdword local_sym
5134 bool MipsAsmParser::parseDirectiveGpDWord() {
5135 MCAsmParser &Parser = getParser();
5136 const MCExpr *Value;
5137 // EmitGPRel64Value requires an expression, so we are using base class
5138 // method to evaluate the expression.
5139 if (getParser().parseExpression(Value))
5141 getParser().getStreamer().EmitGPRel64Value(Value);
5143 if (getLexer().isNot(AsmToken::EndOfStatement))
5144 return Error(getLexer().getLoc(),
5145 "unexpected token, expected end of statement");
5146 Parser.Lex(); // Eat EndOfStatement token.
5150 bool MipsAsmParser::parseDirectiveOption() {
5151 MCAsmParser &Parser = getParser();
5152 // Get the option token.
5153 AsmToken Tok = Parser.getTok();
5154 // At the moment only identifiers are supported.
5155 if (Tok.isNot(AsmToken::Identifier)) {
5156 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5157 Parser.eatToEndOfStatement();
5161 StringRef Option = Tok.getIdentifier();
5163 if (Option == "pic0") {
5164 // MipsAsmParser needs to know if the current PIC mode changes.
5165 IsPicEnabled = false;
5167 getTargetStreamer().emitDirectiveOptionPic0();
5169 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5170 Error(Parser.getTok().getLoc(),
5171 "unexpected token, expected end of statement");
5172 Parser.eatToEndOfStatement();
5177 if (Option == "pic2") {
5178 // MipsAsmParser needs to know if the current PIC mode changes.
5179 IsPicEnabled = true;
5181 getTargetStreamer().emitDirectiveOptionPic2();
5183 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5184 Error(Parser.getTok().getLoc(),
5185 "unexpected token, expected end of statement");
5186 Parser.eatToEndOfStatement();
5192 Warning(Parser.getTok().getLoc(),
5193 "unknown option, expected 'pic0' or 'pic2'");
5194 Parser.eatToEndOfStatement();
5198 /// parseInsnDirective
5200 bool MipsAsmParser::parseInsnDirective() {
5201 // If this is not the end of the statement, report an error.
5202 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5203 reportParseError("unexpected token, expected end of statement");
5207 // The actual label marking happens in
5208 // MipsELFStreamer::createPendingLabelRelocs().
5209 getTargetStreamer().emitDirectiveInsn();
5211 getParser().Lex(); // Eat EndOfStatement token.
5215 /// parseDirectiveModule
5216 /// ::= .module oddspreg
5217 /// ::= .module nooddspreg
5218 /// ::= .module fp=value
5219 /// ::= .module softfloat
5220 /// ::= .module hardfloat
5221 bool MipsAsmParser::parseDirectiveModule() {
5222 MCAsmParser &Parser = getParser();
5223 MCAsmLexer &Lexer = getLexer();
5224 SMLoc L = Lexer.getLoc();
5226 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5227 // TODO : get a better message.
5228 reportParseError(".module directive must appear before any code");
5233 if (Parser.parseIdentifier(Option)) {
5234 reportParseError("expected .module option identifier");
5238 if (Option == "oddspreg") {
5239 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5241 // Synchronize the abiflags information with the FeatureBits information we
5243 getTargetStreamer().updateABIInfo(*this);
5245 // If printing assembly, use the recently updated abiflags information.
5246 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5247 // emitted at the end).
5248 getTargetStreamer().emitDirectiveModuleOddSPReg();
5250 // If this is not the end of the statement, report an error.
5251 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5252 reportParseError("unexpected token, expected end of statement");
5256 return false; // parseDirectiveModule has finished successfully.
5257 } else if (Option == "nooddspreg") {
5259 Error(L, "'.module nooddspreg' requires the O32 ABI");
5263 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5265 // Synchronize the abiflags information with the FeatureBits information we
5267 getTargetStreamer().updateABIInfo(*this);
5269 // If printing assembly, use the recently updated abiflags information.
5270 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5271 // emitted at the end).
5272 getTargetStreamer().emitDirectiveModuleOddSPReg();
5274 // If this is not the end of the statement, report an error.
5275 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5276 reportParseError("unexpected token, expected end of statement");
5280 return false; // parseDirectiveModule has finished successfully.
5281 } else if (Option == "fp") {
5282 return parseDirectiveModuleFP();
5283 } else if (Option == "softfloat") {
5284 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5286 // Synchronize the ABI Flags information with the FeatureBits information we
5288 getTargetStreamer().updateABIInfo(*this);
5290 // If printing assembly, use the recently updated ABI Flags information.
5291 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5293 getTargetStreamer().emitDirectiveModuleSoftFloat();
5295 // If this is not the end of the statement, report an error.
5296 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5297 reportParseError("unexpected token, expected end of statement");
5301 return false; // parseDirectiveModule has finished successfully.
5302 } else if (Option == "hardfloat") {
5303 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5305 // Synchronize the ABI Flags information with the FeatureBits information we
5307 getTargetStreamer().updateABIInfo(*this);
5309 // If printing assembly, use the recently updated ABI Flags information.
5310 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5312 getTargetStreamer().emitDirectiveModuleHardFloat();
5314 // If this is not the end of the statement, report an error.
5315 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5316 reportParseError("unexpected token, expected end of statement");
5320 return false; // parseDirectiveModule has finished successfully.
5322 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5326 /// parseDirectiveModuleFP
5330 bool MipsAsmParser::parseDirectiveModuleFP() {
5331 MCAsmParser &Parser = getParser();
5332 MCAsmLexer &Lexer = getLexer();
5334 if (Lexer.isNot(AsmToken::Equal)) {
5335 reportParseError("unexpected token, expected equals sign '='");
5338 Parser.Lex(); // Eat '=' token.
5340 MipsABIFlagsSection::FpABIKind FpABI;
5341 if (!parseFpABIValue(FpABI, ".module"))
5344 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5345 reportParseError("unexpected token, expected end of statement");
5349 // Synchronize the abiflags information with the FeatureBits information we
5351 getTargetStreamer().updateABIInfo(*this);
5353 // If printing assembly, use the recently updated abiflags information.
5354 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5355 // emitted at the end).
5356 getTargetStreamer().emitDirectiveModuleFP();
5358 Parser.Lex(); // Consume the EndOfStatement.
5362 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5363 StringRef Directive) {
5364 MCAsmParser &Parser = getParser();
5365 MCAsmLexer &Lexer = getLexer();
5366 bool ModuleLevelOptions = Directive == ".module";
5368 if (Lexer.is(AsmToken::Identifier)) {
5369 StringRef Value = Parser.getTok().getString();
5372 if (Value != "xx") {
5373 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5378 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5382 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5383 if (ModuleLevelOptions) {
5384 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5385 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5387 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5388 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5393 if (Lexer.is(AsmToken::Integer)) {
5394 unsigned Value = Parser.getTok().getIntVal();
5397 if (Value != 32 && Value != 64) {
5398 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5404 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5408 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5409 if (ModuleLevelOptions) {
5410 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5411 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5413 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5414 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5417 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5418 if (ModuleLevelOptions) {
5419 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5420 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5422 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5423 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5433 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5434 MCAsmParser &Parser = getParser();
5435 StringRef IDVal = DirectiveID.getString();
5437 if (IDVal == ".cpload")
5438 return parseDirectiveCpLoad(DirectiveID.getLoc());
5439 if (IDVal == ".cprestore")
5440 return parseDirectiveCpRestore(DirectiveID.getLoc());
5441 if (IDVal == ".dword") {
5442 parseDataDirective(8, DirectiveID.getLoc());
5445 if (IDVal == ".ent") {
5446 StringRef SymbolName;
5448 if (Parser.parseIdentifier(SymbolName)) {
5449 reportParseError("expected identifier after .ent");
5453 // There's an undocumented extension that allows an integer to
5454 // follow the name of the procedure which AFAICS is ignored by GAS.
5455 // Example: .ent foo,2
5456 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5457 if (getLexer().isNot(AsmToken::Comma)) {
5458 // Even though we accept this undocumented extension for compatibility
5459 // reasons, the additional integer argument does not actually change
5460 // the behaviour of the '.ent' directive, so we would like to discourage
5461 // its use. We do this by not referring to the extended version in
5462 // error messages which are not directly related to its use.
5463 reportParseError("unexpected token, expected end of statement");
5466 Parser.Lex(); // Eat the comma.
5467 const MCExpr *DummyNumber;
5468 int64_t DummyNumberVal;
5469 // If the user was explicitly trying to use the extended version,
5470 // we still give helpful extension-related error messages.
5471 if (Parser.parseExpression(DummyNumber)) {
5472 reportParseError("expected number after comma");
5475 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5476 reportParseError("expected an absolute expression after comma");
5481 // If this is not the end of the statement, report an error.
5482 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5483 reportParseError("unexpected token, expected end of statement");
5487 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5489 getTargetStreamer().emitDirectiveEnt(*Sym);
5491 IsCpRestoreSet = false;
5495 if (IDVal == ".end") {
5496 StringRef SymbolName;
5498 if (Parser.parseIdentifier(SymbolName)) {
5499 reportParseError("expected identifier after .end");
5503 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5504 reportParseError("unexpected token, expected end of statement");
5508 if (CurrentFn == nullptr) {
5509 reportParseError(".end used without .ent");
5513 if ((SymbolName != CurrentFn->getName())) {
5514 reportParseError(".end symbol does not match .ent symbol");
5518 getTargetStreamer().emitDirectiveEnd(SymbolName);
5519 CurrentFn = nullptr;
5520 IsCpRestoreSet = false;
5524 if (IDVal == ".frame") {
5525 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5526 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5527 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5528 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5529 reportParseError("expected stack register");
5533 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5534 if (!StackRegOpnd.isGPRAsmReg()) {
5535 reportParseError(StackRegOpnd.getStartLoc(),
5536 "expected general purpose register");
5539 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5541 if (Parser.getTok().is(AsmToken::Comma))
5544 reportParseError("unexpected token, expected comma");
5548 // Parse the frame size.
5549 const MCExpr *FrameSize;
5550 int64_t FrameSizeVal;
5552 if (Parser.parseExpression(FrameSize)) {
5553 reportParseError("expected frame size value");
5557 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5558 reportParseError("frame size not an absolute expression");
5562 if (Parser.getTok().is(AsmToken::Comma))
5565 reportParseError("unexpected token, expected comma");
5569 // Parse the return register.
5571 ResTy = parseAnyRegister(TmpReg);
5572 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5573 reportParseError("expected return register");
5577 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5578 if (!ReturnRegOpnd.isGPRAsmReg()) {
5579 reportParseError(ReturnRegOpnd.getStartLoc(),
5580 "expected general purpose register");
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 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5591 ReturnRegOpnd.getGPR32Reg());
5592 IsCpRestoreSet = false;
5596 if (IDVal == ".set") {
5597 return parseDirectiveSet();
5600 if (IDVal == ".mask" || IDVal == ".fmask") {
5601 // .mask bitmask, frame_offset
5602 // bitmask: One bit for each register used.
5603 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5604 // first register is expected to be saved.
5606 // .mask 0x80000000, -4
5607 // .fmask 0x80000000, -4
5610 // Parse the bitmask
5611 const MCExpr *BitMask;
5614 if (Parser.parseExpression(BitMask)) {
5615 reportParseError("expected bitmask value");
5619 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5620 reportParseError("bitmask not an absolute expression");
5624 if (Parser.getTok().is(AsmToken::Comma))
5627 reportParseError("unexpected token, expected comma");
5631 // Parse the frame_offset
5632 const MCExpr *FrameOffset;
5633 int64_t FrameOffsetVal;
5635 if (Parser.parseExpression(FrameOffset)) {
5636 reportParseError("expected frame offset value");
5640 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5641 reportParseError("frame offset not an absolute expression");
5645 // If this is not the end of the statement, report an error.
5646 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5647 reportParseError("unexpected token, expected end of statement");
5651 if (IDVal == ".mask")
5652 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5654 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5658 if (IDVal == ".nan")
5659 return parseDirectiveNaN();
5661 if (IDVal == ".gpword") {
5662 parseDirectiveGpWord();
5666 if (IDVal == ".gpdword") {
5667 parseDirectiveGpDWord();
5671 if (IDVal == ".word") {
5672 parseDataDirective(4, DirectiveID.getLoc());
5676 if (IDVal == ".option")
5677 return parseDirectiveOption();
5679 if (IDVal == ".abicalls") {
5680 getTargetStreamer().emitDirectiveAbiCalls();
5681 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5682 Error(Parser.getTok().getLoc(),
5683 "unexpected token, expected end of statement");
5685 Parser.eatToEndOfStatement();
5690 if (IDVal == ".cpsetup")
5691 return parseDirectiveCPSetup();
5693 if (IDVal == ".cpreturn")
5694 return parseDirectiveCPReturn();
5696 if (IDVal == ".module")
5697 return parseDirectiveModule();
5699 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5700 return parseInternalDirectiveReallowModule();
5702 if (IDVal == ".insn")
5703 return parseInsnDirective();
5708 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5709 // If this is not the end of the statement, report an error.
5710 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5711 reportParseError("unexpected token, expected end of statement");
5715 getTargetStreamer().reallowModuleDirective();
5717 getParser().Lex(); // Eat EndOfStatement token.
5721 extern "C" void LLVMInitializeMipsAsmParser() {
5722 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5723 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5724 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5725 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5728 #define GET_REGISTER_MATCHER
5729 #define GET_MATCHER_IMPLEMENTATION
5730 #include "MipsGenAsmMatcher.inc"