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::BLTImmMacro:
1941 case Mips::BLEImmMacro:
1942 case Mips::BGEImmMacro:
1943 case Mips::BGTImmMacro:
1944 case Mips::BLTUImmMacro:
1945 case Mips::BLEUImmMacro:
1946 case Mips::BGEUImmMacro:
1947 case Mips::BGTUImmMacro:
1948 case Mips::BLTLImmMacro:
1949 case Mips::BLELImmMacro:
1950 case Mips::BGELImmMacro:
1951 case Mips::BGTLImmMacro:
1952 case Mips::BLTULImmMacro:
1953 case Mips::BLEULImmMacro:
1954 case Mips::BGEULImmMacro:
1955 case Mips::BGTULImmMacro:
1956 case Mips::SDivMacro:
1957 case Mips::UDivMacro:
1958 case Mips::DSDivMacro:
1959 case Mips::DUDivMacro:
1968 if ((Inst.getNumOperands() == 3) &&
1969 Inst.getOperand(0).isReg() &&
1970 Inst.getOperand(1).isReg() &&
1971 Inst.getOperand(2).isImm()) {
1972 int64_t ImmValue = Inst.getOperand(2).getImm();
1973 return !isInt<16>(ImmValue);
1979 if ((Inst.getNumOperands() == 3) &&
1980 Inst.getOperand(0).isReg() &&
1981 Inst.getOperand(1).isReg() &&
1982 Inst.getOperand(2).isImm()) {
1983 int64_t ImmValue = Inst.getOperand(2).getImm();
1984 return !isUInt<16>(ImmValue);
1992 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1993 SmallVectorImpl<MCInst> &Instructions) {
1994 switch (Inst.getOpcode()) {
1995 default: llvm_unreachable("unimplemented expansion");
1996 case Mips::LoadImm32:
1997 return expandLoadImm(Inst, true, IDLoc, Instructions);
1998 case Mips::LoadImm64:
1999 return expandLoadImm(Inst, false, IDLoc, Instructions);
2000 case Mips::LoadAddrImm32:
2001 case Mips::LoadAddrImm64:
2002 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2003 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2004 "expected immediate operand kind");
2006 return expandLoadAddress(
2007 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
2008 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
2009 case Mips::LoadAddrReg32:
2010 case Mips::LoadAddrReg64:
2011 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2012 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2013 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2014 "expected immediate operand kind");
2016 return expandLoadAddress(
2017 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
2018 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
2019 case Mips::B_MM_Pseudo:
2020 case Mips::B_MMR6_Pseudo:
2021 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
2024 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
2025 case Mips::JalOneReg:
2026 case Mips::JalTwoReg:
2027 return expandJalWithRegs(Inst, IDLoc, Instructions);
2030 return expandBranchImm(Inst, IDLoc, Instructions);
2047 case Mips::BLTImmMacro:
2048 case Mips::BLEImmMacro:
2049 case Mips::BGEImmMacro:
2050 case Mips::BGTImmMacro:
2051 case Mips::BLTUImmMacro:
2052 case Mips::BLEUImmMacro:
2053 case Mips::BGEUImmMacro:
2054 case Mips::BGTUImmMacro:
2055 case Mips::BLTLImmMacro:
2056 case Mips::BLELImmMacro:
2057 case Mips::BGELImmMacro:
2058 case Mips::BGTLImmMacro:
2059 case Mips::BLTULImmMacro:
2060 case Mips::BLEULImmMacro:
2061 case Mips::BGEULImmMacro:
2062 case Mips::BGTULImmMacro:
2063 return expandCondBranches(Inst, IDLoc, Instructions);
2064 case Mips::SDivMacro:
2065 return expandDiv(Inst, IDLoc, Instructions, false, true);
2066 case Mips::DSDivMacro:
2067 return expandDiv(Inst, IDLoc, Instructions, true, true);
2068 case Mips::UDivMacro:
2069 return expandDiv(Inst, IDLoc, Instructions, false, false);
2070 case Mips::DUDivMacro:
2071 return expandDiv(Inst, IDLoc, Instructions, true, false);
2073 return expandUlhu(Inst, IDLoc, Instructions);
2075 return expandUlw(Inst, IDLoc, Instructions);
2084 return expandAliasImmediate(Inst, IDLoc, Instructions);
2088 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2089 SmallVectorImpl<MCInst> &Instructions) {
2090 // Create a JALR instruction which is going to replace the pseudo-JAL.
2092 JalrInst.setLoc(IDLoc);
2093 const MCOperand FirstRegOp = Inst.getOperand(0);
2094 const unsigned Opcode = Inst.getOpcode();
2096 if (Opcode == Mips::JalOneReg) {
2097 // jal $rs => jalr $rs
2098 if (IsCpRestoreSet && inMicroMipsMode()) {
2099 JalrInst.setOpcode(Mips::JALRS16_MM);
2100 JalrInst.addOperand(FirstRegOp);
2101 } else if (inMicroMipsMode()) {
2102 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2103 JalrInst.addOperand(FirstRegOp);
2105 JalrInst.setOpcode(Mips::JALR);
2106 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2107 JalrInst.addOperand(FirstRegOp);
2109 } else if (Opcode == Mips::JalTwoReg) {
2110 // jal $rd, $rs => jalr $rd, $rs
2111 if (IsCpRestoreSet && inMicroMipsMode())
2112 JalrInst.setOpcode(Mips::JALRS_MM);
2114 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2115 JalrInst.addOperand(FirstRegOp);
2116 const MCOperand SecondRegOp = Inst.getOperand(1);
2117 JalrInst.addOperand(SecondRegOp);
2119 Instructions.push_back(JalrInst);
2121 // If .set reorder is active and branch instruction has a delay slot,
2122 // emit a NOP after it.
2123 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2124 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2125 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2131 /// Can the value be represented by a unsigned N-bit value and a shift left?
2132 template<unsigned N>
2133 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2134 unsigned BitNum = findFirstSet(x);
2136 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2139 /// Load (or add) an immediate into a register.
2141 /// @param ImmValue The immediate to load.
2142 /// @param DstReg The register that will hold the immediate.
2143 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2144 /// for a simple initialization.
2145 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2146 /// @param IsAddress True if the immediate represents an address. False if it
2148 /// @param IDLoc Location of the immediate in the source file.
2149 /// @param Instructions The instructions emitted by this expansion.
2150 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2151 unsigned SrcReg, bool Is32BitImm,
2152 bool IsAddress, SMLoc IDLoc,
2153 SmallVectorImpl<MCInst> &Instructions) {
2154 if (!Is32BitImm && !isGP64bit()) {
2155 Error(IDLoc, "instruction requires a 64-bit architecture");
2160 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2161 // Sign extend up to 64-bit so that the predicates match the hardware
2162 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2164 ImmValue = SignExtend64<32>(ImmValue);
2166 Error(IDLoc, "instruction requires a 32-bit immediate");
2171 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2172 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2174 bool UseSrcReg = false;
2175 if (SrcReg != Mips::NoRegister)
2178 unsigned TmpReg = DstReg;
2179 if (UseSrcReg && (DstReg == SrcReg)) {
2180 // At this point we need AT to perform the expansions and we exit if it is
2182 unsigned ATReg = getATReg(IDLoc);
2188 if (isInt<16>(ImmValue)) {
2192 // This doesn't quite follow the usual ABI expectations for N32 but matches
2193 // traditional assembler behaviour. N32 would normally use addiu for both
2194 // integers and addresses.
2195 if (IsAddress && !Is32BitImm) {
2196 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2200 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2204 if (isUInt<16>(ImmValue)) {
2205 unsigned TmpReg = DstReg;
2206 if (SrcReg == DstReg) {
2207 TmpReg = getATReg(IDLoc);
2212 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2214 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2218 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2219 warnIfNoMacro(IDLoc);
2221 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2222 uint16_t Bits15To0 = ImmValue & 0xffff;
2224 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2225 // Traditional behaviour seems to special case this particular value. It's
2226 // not clear why other masks are handled differently.
2227 if (ImmValue == 0xffffffff) {
2228 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2229 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2231 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2235 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2237 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2238 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2240 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2242 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2246 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2248 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2250 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2254 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2256 Error(IDLoc, "instruction requires a 32-bit immediate");
2260 // Traditionally, these immediates are shifted as little as possible and as
2261 // such we align the most significant bit to bit 15 of our temporary.
2262 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2263 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2264 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2265 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2266 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2267 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2270 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2275 warnIfNoMacro(IDLoc);
2277 // The remaining case is packed with a sequence of dsll and ori with zeros
2278 // being omitted and any neighbouring dsll's being coalesced.
2279 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2281 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2282 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2283 IDLoc, Instructions))
2286 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2287 // skip it and defer the shift to the next chunk.
2288 unsigned ShiftCarriedForwards = 16;
2289 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2290 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2292 if (ImmChunk != 0) {
2293 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2295 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2296 ShiftCarriedForwards = 0;
2299 ShiftCarriedForwards += 16;
2301 ShiftCarriedForwards -= 16;
2303 // Finish any remaining shifts left by trailing zeros.
2304 if (ShiftCarriedForwards)
2305 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2309 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2314 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2315 SmallVectorImpl<MCInst> &Instructions) {
2316 const MCOperand &ImmOp = Inst.getOperand(1);
2317 assert(ImmOp.isImm() && "expected immediate operand kind");
2318 const MCOperand &DstRegOp = Inst.getOperand(0);
2319 assert(DstRegOp.isReg() && "expected register operand kind");
2321 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2322 Is32BitImm, false, IDLoc, Instructions))
2328 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2329 const MCOperand &Offset,
2330 bool Is32BitAddress, SMLoc IDLoc,
2331 SmallVectorImpl<MCInst> &Instructions) {
2332 // la can't produce a usable address when addresses are 64-bit.
2333 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2334 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2335 // We currently can't do this because we depend on the equality
2336 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2337 Error(IDLoc, "la used to load 64-bit address");
2338 // Continue as if we had 'dla' instead.
2339 Is32BitAddress = false;
2342 // dla requires 64-bit addresses.
2343 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2344 Error(IDLoc, "instruction requires a 64-bit architecture");
2348 if (!Offset.isImm())
2349 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2350 Is32BitAddress, IDLoc, Instructions);
2352 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2353 IDLoc, Instructions);
2356 bool MipsAsmParser::loadAndAddSymbolAddress(
2357 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2358 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2359 warnIfNoMacro(IDLoc);
2361 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2362 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2363 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2364 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2365 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2367 bool UseSrcReg = SrcReg != Mips::NoRegister;
2369 // This is the 64-bit symbol address expansion.
2370 if (ABI.ArePtrs64bit() && isGP64bit()) {
2371 // We always need AT for the 64-bit expansion.
2372 // If it is not available we exit.
2373 unsigned ATReg = getATReg(IDLoc);
2377 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2378 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2379 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2380 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2382 if (UseSrcReg && (DstReg == SrcReg)) {
2383 // If $rs is the same as $rd:
2384 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2385 // daddiu $at, $at, %higher(sym)
2386 // dsll $at, $at, 16
2387 // daddiu $at, $at, %hi(sym)
2388 // dsll $at, $at, 16
2389 // daddiu $at, $at, %lo(sym)
2390 // daddu $rd, $at, $rd
2391 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2393 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2394 IDLoc, Instructions);
2395 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2396 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2398 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2399 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2401 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2406 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2407 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2408 // lui $at, %hi(sym)
2409 // daddiu $rd, $rd, %higher(sym)
2410 // daddiu $at, $at, %lo(sym)
2411 // dsll32 $rd, $rd, 0
2412 // daddu $rd, $rd, $at
2413 // (daddu $rd, $rd, $rs)
2414 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2416 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2418 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2419 IDLoc, Instructions);
2420 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2422 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2423 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2425 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2430 // And now, the 32-bit symbol address expansion:
2431 // If $rs is the same as $rd:
2432 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2433 // ori $at, $at, %lo(sym)
2434 // addu $rd, $at, $rd
2435 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2436 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2437 // ori $rd, $rd, %lo(sym)
2438 // (addu $rd, $rd, $rs)
2439 unsigned TmpReg = DstReg;
2440 if (UseSrcReg && (DstReg == SrcReg)) {
2441 // If $rs is the same as $rd, we need to use AT.
2442 // If it is not available we exit.
2443 unsigned ATReg = getATReg(IDLoc);
2449 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2450 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2454 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2456 assert(DstReg == TmpReg);
2461 bool MipsAsmParser::expandUncondBranchMMPseudo(
2462 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2463 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2464 "unexpected number of operands");
2466 MCOperand Offset = Inst.getOperand(0);
2467 if (Offset.isExpr()) {
2469 Inst.setOpcode(Mips::BEQ_MM);
2470 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2471 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2472 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2474 assert(Offset.isImm() && "expected immediate operand kind");
2475 if (isInt<11>(Offset.getImm())) {
2476 // If offset fits into 11 bits then this instruction becomes microMIPS
2477 // 16-bit unconditional branch instruction.
2478 if (inMicroMipsMode())
2479 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2481 if (!isInt<17>(Offset.getImm()))
2482 Error(IDLoc, "branch target out of range");
2483 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2484 Error(IDLoc, "branch to misaligned address");
2486 Inst.setOpcode(Mips::BEQ_MM);
2487 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2488 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2489 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2492 Instructions.push_back(Inst);
2494 // If .set reorder is active and branch instruction has a delay slot,
2495 // emit a NOP after it.
2496 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2497 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2498 createNop(true, IDLoc, Instructions);
2503 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2504 SmallVectorImpl<MCInst> &Instructions) {
2505 const MCOperand &DstRegOp = Inst.getOperand(0);
2506 assert(DstRegOp.isReg() && "expected register operand kind");
2508 const MCOperand &ImmOp = Inst.getOperand(1);
2509 assert(ImmOp.isImm() && "expected immediate operand kind");
2511 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2512 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2514 unsigned OpCode = 0;
2515 switch(Inst.getOpcode()) {
2523 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2527 int64_t ImmValue = ImmOp.getImm();
2529 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2532 warnIfNoMacro(IDLoc);
2534 unsigned ATReg = getATReg(IDLoc);
2538 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2539 IDLoc, Instructions))
2542 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2547 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2548 SmallVectorImpl<MCInst> &Instructions,
2549 bool isLoad, bool isImmOpnd) {
2550 unsigned ImmOffset, HiOffset, LoOffset;
2551 const MCExpr *ExprOffset;
2553 // 1st operand is either the source or destination register.
2554 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2555 unsigned RegOpNum = Inst.getOperand(0).getReg();
2556 // 2nd operand is the base register.
2557 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2558 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2559 // 3rd operand is either an immediate or expression.
2561 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2562 ImmOffset = Inst.getOperand(2).getImm();
2563 LoOffset = ImmOffset & 0x0000ffff;
2564 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2565 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2566 if (LoOffset & 0x8000)
2569 ExprOffset = Inst.getOperand(2).getExpr();
2570 // These are some of the types of expansions we perform here:
2571 // 1) lw $8, sym => lui $8, %hi(sym)
2572 // lw $8, %lo(sym)($8)
2573 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2575 // lw $8, %lo(offset)($9)
2576 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2578 // lw $8, %lo(offset)($at)
2579 // 4) sw $8, sym => lui $at, %hi(sym)
2580 // sw $8, %lo(sym)($at)
2581 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2583 // sw $8, %lo(offset)($at)
2584 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2585 // ldc1 $f0, %lo(sym)($at)
2587 // For load instructions we can use the destination register as a temporary
2588 // if base and dst are different (examples 1 and 2) and if the base register
2589 // is general purpose otherwise we must use $at (example 6) and error if it's
2590 // not available. For stores we must use $at (examples 4 and 5) because we
2591 // must not clobber the source register setting up the offset.
2592 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2593 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2594 unsigned RegClassIDOp0 =
2595 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2596 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2597 (RegClassIDOp0 == Mips::GPR64RegClassID);
2598 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2599 TmpRegNum = RegOpNum;
2601 // At this point we need AT to perform the expansions and we exit if it is
2603 TmpRegNum = getATReg(IDLoc);
2608 emitRX(Mips::LUi, TmpRegNum,
2609 isImmOpnd ? MCOperand::createImm(HiOffset)
2610 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2611 IDLoc, Instructions);
2612 // Add temp register to base.
2613 if (BaseRegNum != Mips::ZERO)
2614 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2615 // And finally, create original instruction with low part
2616 // of offset and new base.
2617 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2619 ? MCOperand::createImm(LoOffset)
2620 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2621 IDLoc, Instructions);
2625 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2626 SmallVectorImpl<MCInst> &Instructions) {
2627 unsigned OpNum = Inst.getNumOperands();
2628 unsigned Opcode = Inst.getOpcode();
2629 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2631 assert (Inst.getOperand(OpNum - 1).isImm() &&
2632 Inst.getOperand(OpNum - 2).isReg() &&
2633 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2635 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2636 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2637 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2638 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2639 // It can be implemented as SWM16 or LWM16 instruction.
2640 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2642 Inst.setOpcode(NewOpcode);
2643 Instructions.push_back(Inst);
2647 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2648 SmallVectorImpl<MCInst> &Instructions) {
2649 bool EmittedNoMacroWarning = false;
2650 unsigned PseudoOpcode = Inst.getOpcode();
2651 unsigned SrcReg = Inst.getOperand(0).getReg();
2652 const MCOperand &TrgOp = Inst.getOperand(1);
2653 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2655 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2656 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2660 TrgReg = TrgOp.getReg();
2661 else if (TrgOp.isImm()) {
2662 warnIfNoMacro(IDLoc);
2663 EmittedNoMacroWarning = true;
2665 TrgReg = getATReg(IDLoc);
2669 switch(PseudoOpcode) {
2671 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2672 case Mips::BLTImmMacro:
2673 PseudoOpcode = Mips::BLT;
2675 case Mips::BLEImmMacro:
2676 PseudoOpcode = Mips::BLE;
2678 case Mips::BGEImmMacro:
2679 PseudoOpcode = Mips::BGE;
2681 case Mips::BGTImmMacro:
2682 PseudoOpcode = Mips::BGT;
2684 case Mips::BLTUImmMacro:
2685 PseudoOpcode = Mips::BLTU;
2687 case Mips::BLEUImmMacro:
2688 PseudoOpcode = Mips::BLEU;
2690 case Mips::BGEUImmMacro:
2691 PseudoOpcode = Mips::BGEU;
2693 case Mips::BGTUImmMacro:
2694 PseudoOpcode = Mips::BGTU;
2696 case Mips::BLTLImmMacro:
2697 PseudoOpcode = Mips::BLTL;
2699 case Mips::BLELImmMacro:
2700 PseudoOpcode = Mips::BLEL;
2702 case Mips::BGELImmMacro:
2703 PseudoOpcode = Mips::BGEL;
2705 case Mips::BGTLImmMacro:
2706 PseudoOpcode = Mips::BGTL;
2708 case Mips::BLTULImmMacro:
2709 PseudoOpcode = Mips::BLTUL;
2711 case Mips::BLEULImmMacro:
2712 PseudoOpcode = Mips::BLEUL;
2714 case Mips::BGEULImmMacro:
2715 PseudoOpcode = Mips::BGEUL;
2717 case Mips::BGTULImmMacro:
2718 PseudoOpcode = Mips::BGTUL;
2722 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2723 false, IDLoc, Instructions))
2727 switch (PseudoOpcode) {
2732 AcceptsEquality = false;
2733 ReverseOrderSLT = false;
2734 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2735 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2736 ZeroSrcOpcode = Mips::BGTZ;
2737 ZeroTrgOpcode = Mips::BLTZ;
2743 AcceptsEquality = true;
2744 ReverseOrderSLT = true;
2745 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2746 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2747 ZeroSrcOpcode = Mips::BGEZ;
2748 ZeroTrgOpcode = Mips::BLEZ;
2754 AcceptsEquality = true;
2755 ReverseOrderSLT = false;
2756 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2757 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2758 ZeroSrcOpcode = Mips::BLEZ;
2759 ZeroTrgOpcode = Mips::BGEZ;
2765 AcceptsEquality = false;
2766 ReverseOrderSLT = true;
2767 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2768 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2769 ZeroSrcOpcode = Mips::BLTZ;
2770 ZeroTrgOpcode = Mips::BGTZ;
2773 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2776 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2777 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2778 if (IsSrcRegZero && IsTrgRegZero) {
2779 // FIXME: All of these Opcode-specific if's are needed for compatibility
2780 // with GAS' behaviour. However, they may not generate the most efficient
2781 // code in some circumstances.
2782 if (PseudoOpcode == Mips::BLT) {
2783 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2787 if (PseudoOpcode == Mips::BLE) {
2788 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2790 Warning(IDLoc, "branch is always taken");
2793 if (PseudoOpcode == Mips::BGE) {
2794 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2796 Warning(IDLoc, "branch is always taken");
2799 if (PseudoOpcode == Mips::BGT) {
2800 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2804 if (PseudoOpcode == Mips::BGTU) {
2805 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2806 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2809 if (AcceptsEquality) {
2810 // If both registers are $0 and the pseudo-branch accepts equality, it
2811 // will always be taken, so we emit an unconditional branch.
2812 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2813 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2814 Warning(IDLoc, "branch is always taken");
2817 // If both registers are $0 and the pseudo-branch does not accept
2818 // equality, it will never be taken, so we don't have to emit anything.
2821 if (IsSrcRegZero || IsTrgRegZero) {
2822 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2823 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2824 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2825 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2826 // the pseudo-branch will never be taken, so we don't emit anything.
2827 // This only applies to unsigned pseudo-branches.
2830 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2831 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2832 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2833 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2834 // the pseudo-branch will always be taken, so we emit an unconditional
2836 // This only applies to unsigned pseudo-branches.
2837 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2838 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2839 Warning(IDLoc, "branch is always taken");
2843 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2844 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2845 // the pseudo-branch will be taken only when the non-zero register is
2846 // different from 0, so we emit a BNEZ.
2848 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2849 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2850 // the pseudo-branch will be taken only when the non-zero register is
2851 // equal to 0, so we emit a BEQZ.
2853 // Because only BLEU and BGEU branch on equality, we can use the
2854 // AcceptsEquality variable to decide when to emit the BEQZ.
2855 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2856 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2857 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2860 // If we have a signed pseudo-branch and one of the registers is $0,
2861 // we can use an appropriate compare-to-zero branch. We select which one
2862 // to use in the switch statement above.
2863 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2864 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2865 IDLoc, Instructions);
2869 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2870 // expansions. If it is not available, we return.
2871 unsigned ATRegNum = getATReg(IDLoc);
2875 if (!EmittedNoMacroWarning)
2876 warnIfNoMacro(IDLoc);
2878 // SLT fits well with 2 of our 4 pseudo-branches:
2879 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2880 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2881 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2882 // This is accomplished by using a BNEZ with the result of the SLT.
2884 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2885 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2886 // Because only BGE and BLE branch on equality, we can use the
2887 // AcceptsEquality variable to decide when to emit the BEQZ.
2888 // Note that the order of the SLT arguments doesn't change between
2891 // The same applies to the unsigned variants, except that SLTu is used
2893 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2894 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2895 IDLoc, Instructions);
2897 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2898 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2899 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2904 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2905 SmallVectorImpl<MCInst> &Instructions,
2906 const bool IsMips64, const bool Signed) {
2907 if (hasMips32r6()) {
2908 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2912 warnIfNoMacro(IDLoc);
2914 const MCOperand &RsRegOp = Inst.getOperand(0);
2915 assert(RsRegOp.isReg() && "expected register operand kind");
2916 unsigned RsReg = RsRegOp.getReg();
2918 const MCOperand &RtRegOp = Inst.getOperand(1);
2919 assert(RtRegOp.isReg() && "expected register operand kind");
2920 unsigned RtReg = RtRegOp.getReg();
2925 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2926 ZeroReg = Mips::ZERO_64;
2928 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2929 ZeroReg = Mips::ZERO;
2932 bool UseTraps = useTraps();
2934 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2935 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2936 Warning(IDLoc, "dividing zero by zero");
2938 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2940 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2944 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2948 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2953 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2954 Warning(IDLoc, "division by zero");
2957 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2961 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2966 // FIXME: The values for these two BranchTarget variables may be different in
2967 // micromips. These magic numbers need to be removed.
2968 unsigned BranchTargetNoTraps;
2969 unsigned BranchTarget;
2972 BranchTarget = IsMips64 ? 12 : 8;
2973 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2975 BranchTarget = IsMips64 ? 20 : 16;
2976 BranchTargetNoTraps = 8;
2977 // Branch to the li instruction.
2978 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2982 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2985 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2988 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2992 unsigned ATReg = getATReg(IDLoc);
2996 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2998 // Branch to the mflo instruction.
2999 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3000 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
3001 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
3003 // Branch to the mflo instruction.
3004 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3005 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
3009 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
3011 // Branch to the mflo instruction.
3012 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
3013 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
3014 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
3016 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3020 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
3021 SmallVectorImpl<MCInst> &Instructions) {
3022 if (hasMips32r6() || hasMips64r6()) {
3023 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3027 warnIfNoMacro(IDLoc);
3029 const MCOperand &DstRegOp = Inst.getOperand(0);
3030 assert(DstRegOp.isReg() && "expected register operand kind");
3032 const MCOperand &SrcRegOp = Inst.getOperand(1);
3033 assert(SrcRegOp.isReg() && "expected register operand kind");
3035 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3036 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3038 unsigned DstReg = DstRegOp.getReg();
3039 unsigned SrcReg = SrcRegOp.getReg();
3040 int64_t OffsetValue = OffsetImmOp.getImm();
3042 // NOTE: We always need AT for ULHU, as it is always used as the source
3043 // register for one of the LBu's.
3044 unsigned ATReg = getATReg(IDLoc);
3048 // When the value of offset+1 does not fit in 16 bits, we have to load the
3049 // offset in AT, (D)ADDu the original source register (if there was one), and
3050 // then use AT as the source register for the 2 generated LBu's.
3051 bool LoadedOffsetInAT = false;
3052 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3053 LoadedOffsetInAT = true;
3055 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3056 true, IDLoc, Instructions))
3059 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3060 // because it will make our output more similar to GAS'. For example,
3061 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3062 // instead of just an "ori $1, $9, 32768".
3063 // NOTE: If there is no source register specified in the ULHU, the parser
3064 // will interpret it as $0.
3065 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3066 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3069 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3070 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3071 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3073 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3075 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3076 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3078 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3079 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3082 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3084 emitRRI(Mips::LBu, FirstLbuDstReg, LbuSrcReg, FirstLbuOffset, IDLoc,
3087 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3090 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3092 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3097 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3098 SmallVectorImpl<MCInst> &Instructions) {
3099 if (hasMips32r6() || hasMips64r6()) {
3100 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3104 const MCOperand &DstRegOp = Inst.getOperand(0);
3105 assert(DstRegOp.isReg() && "expected register operand kind");
3107 const MCOperand &SrcRegOp = Inst.getOperand(1);
3108 assert(SrcRegOp.isReg() && "expected register operand kind");
3110 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3111 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3113 unsigned SrcReg = SrcRegOp.getReg();
3114 int64_t OffsetValue = OffsetImmOp.getImm();
3117 // When the value of offset+3 does not fit in 16 bits, we have to load the
3118 // offset in AT, (D)ADDu the original source register (if there was one), and
3119 // then use AT as the source register for the generated LWL and LWR.
3120 bool LoadedOffsetInAT = false;
3121 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3122 ATReg = getATReg(IDLoc);
3125 LoadedOffsetInAT = true;
3127 warnIfNoMacro(IDLoc);
3129 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3130 true, IDLoc, Instructions))
3133 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3134 // because it will make our output more similar to GAS'. For example,
3135 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3136 // instead of just an "ori $1, $9, 32768".
3137 // NOTE: If there is no source register specified in the ULW, the parser
3138 // will interpret it as $0.
3139 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3140 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3143 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3144 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3146 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3147 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3149 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3150 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3153 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3156 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3162 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3163 SmallVectorImpl<MCInst> &Instructions) {
3165 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3166 assert (Inst.getOperand(0).isReg() &&
3167 Inst.getOperand(1).isReg() &&
3168 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3170 unsigned ATReg = Mips::NoRegister;
3171 unsigned FinalDstReg = Mips::NoRegister;
3172 unsigned DstReg = Inst.getOperand(0).getReg();
3173 unsigned SrcReg = Inst.getOperand(1).getReg();
3174 int64_t ImmValue = Inst.getOperand(2).getImm();
3176 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3178 unsigned FinalOpcode = Inst.getOpcode();
3180 if (DstReg == SrcReg) {
3181 ATReg = getATReg(Inst.getLoc());
3184 FinalDstReg = DstReg;
3188 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3189 switch (FinalOpcode) {
3191 llvm_unreachable("unimplemented expansion");
3193 FinalOpcode = Mips::ADD;
3196 FinalOpcode = Mips::ADDu;
3199 FinalOpcode = Mips::AND;
3201 case (Mips::NORImm):
3202 FinalOpcode = Mips::NOR;
3205 FinalOpcode = Mips::OR;
3208 FinalOpcode = Mips::SLT;
3211 FinalOpcode = Mips::SLTu;
3214 FinalOpcode = Mips::XOR;
3218 if (FinalDstReg == Mips::NoRegister)
3219 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3221 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3228 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3229 SmallVectorImpl<MCInst> &Instructions) {
3230 if (hasShortDelaySlot)
3231 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3233 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3236 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3237 unsigned TrgReg, bool Is64Bit,
3238 SmallVectorImpl<MCInst> &Instructions) {
3239 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3243 void MipsAsmParser::createCpRestoreMemOp(
3244 bool IsLoad, int StackOffset, SMLoc IDLoc,
3245 SmallVectorImpl<MCInst> &Instructions) {
3246 // If the offset can not fit into 16 bits, we need to expand.
3247 if (!isInt<16>(StackOffset)) {
3249 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3250 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3251 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3252 MemInst.addOperand(MCOperand::createImm(StackOffset));
3253 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3257 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3261 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3262 // As described by the Mips32r2 spec, the registers Rd and Rs for
3263 // jalr.hb must be different.
3264 unsigned Opcode = Inst.getOpcode();
3266 if (Opcode == Mips::JALR_HB &&
3267 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3268 return Match_RequiresDifferentSrcAndDst;
3270 return Match_Success;
3273 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3274 OperandVector &Operands,
3276 uint64_t &ErrorInfo,
3277 bool MatchingInlineAsm) {
3280 SmallVector<MCInst, 8> Instructions;
3281 unsigned MatchResult =
3282 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3284 switch (MatchResult) {
3285 case Match_Success: {
3286 if (processInstruction(Inst, IDLoc, Instructions))
3288 for (unsigned i = 0; i < Instructions.size(); i++)
3289 Out.EmitInstruction(Instructions[i], STI);
3292 case Match_MissingFeature:
3293 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3295 case Match_InvalidOperand: {
3296 SMLoc ErrorLoc = IDLoc;
3297 if (ErrorInfo != ~0ULL) {
3298 if (ErrorInfo >= Operands.size())
3299 return Error(IDLoc, "too few operands for instruction");
3301 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3302 if (ErrorLoc == SMLoc())
3306 return Error(ErrorLoc, "invalid operand for instruction");
3308 case Match_MnemonicFail:
3309 return Error(IDLoc, "invalid instruction");
3310 case Match_RequiresDifferentSrcAndDst:
3311 return Error(IDLoc, "source and destination must be different");
3314 llvm_unreachable("Implement any new match types added!");
3317 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3318 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3319 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3320 ") without \".set noat\"");
3323 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3324 if (!AssemblerOptions.back()->isMacro())
3325 Warning(Loc, "macro instruction expanded into multiple instructions");
3329 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3330 SMRange Range, bool ShowColors) {
3331 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3332 Range, SMFixIt(Range, FixMsg),
3336 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3339 CC = StringSwitch<unsigned>(Name)
3375 if (!(isABI_N32() || isABI_N64()))
3378 if (12 <= CC && CC <= 15) {
3379 // Name is one of t4-t7
3380 AsmToken RegTok = getLexer().peekTok();
3381 SMRange RegRange = RegTok.getLocRange();
3383 StringRef FixedName = StringSwitch<StringRef>(Name)
3389 assert(FixedName != "" && "Register name is not one of t4-t7.");
3391 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3392 "Did you mean $" + FixedName + "?", RegRange);
3395 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3396 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3397 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3398 if (8 <= CC && CC <= 11)
3402 CC = StringSwitch<unsigned>(Name)
3414 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3417 CC = StringSwitch<unsigned>(Name)
3418 .Case("hwr_cpunum", 0)
3419 .Case("hwr_synci_step", 1)
3421 .Case("hwr_ccres", 3)
3422 .Case("hwr_ulr", 29)
3428 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3430 if (Name[0] == 'f') {
3431 StringRef NumString = Name.substr(1);
3433 if (NumString.getAsInteger(10, IntVal))
3434 return -1; // This is not an integer.
3435 if (IntVal > 31) // Maximum index for fpu register.
3442 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3444 if (Name.startswith("fcc")) {
3445 StringRef NumString = Name.substr(3);
3447 if (NumString.getAsInteger(10, IntVal))
3448 return -1; // This is not an integer.
3449 if (IntVal > 7) // There are only 8 fcc registers.
3456 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3458 if (Name.startswith("ac")) {
3459 StringRef NumString = Name.substr(2);
3461 if (NumString.getAsInteger(10, IntVal))
3462 return -1; // This is not an integer.
3463 if (IntVal > 3) // There are only 3 acc registers.
3470 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3473 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3482 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3485 CC = StringSwitch<unsigned>(Name)
3488 .Case("msaaccess", 2)
3490 .Case("msamodify", 4)
3491 .Case("msarequest", 5)
3493 .Case("msaunmap", 7)
3499 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3500 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3502 reportParseError(Loc,
3503 "pseudo-instruction requires $at, which is not available");
3506 unsigned AT = getReg(
3507 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3511 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3512 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3515 unsigned MipsAsmParser::getGPR(int RegNo) {
3516 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3520 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3522 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3525 return getReg(RegClass, RegNum);
3528 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3529 MCAsmParser &Parser = getParser();
3530 DEBUG(dbgs() << "parseOperand\n");
3532 // Check if the current operand has a custom associated parser, if so, try to
3533 // custom parse the operand, or fallback to the general approach.
3534 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3535 if (ResTy == MatchOperand_Success)
3537 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3538 // there was a match, but an error occurred, in which case, just return that
3539 // the operand parsing failed.
3540 if (ResTy == MatchOperand_ParseFail)
3543 DEBUG(dbgs() << ".. Generic Parser\n");
3545 switch (getLexer().getKind()) {
3547 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3549 case AsmToken::Dollar: {
3550 // Parse the register.
3551 SMLoc S = Parser.getTok().getLoc();
3553 // Almost all registers have been parsed by custom parsers. There is only
3554 // one exception to this. $zero (and it's alias $0) will reach this point
3555 // for div, divu, and similar instructions because it is not an operand
3556 // to the instruction definition but an explicit register. Special case
3557 // this situation for now.
3558 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3561 // Maybe it is a symbol reference.
3562 StringRef Identifier;
3563 if (Parser.parseIdentifier(Identifier))
3566 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3567 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3568 // Otherwise create a symbol reference.
3570 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3572 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3575 // Else drop to expression parsing.
3576 case AsmToken::LParen:
3577 case AsmToken::Minus:
3578 case AsmToken::Plus:
3579 case AsmToken::Integer:
3580 case AsmToken::Tilde:
3581 case AsmToken::String: {
3582 DEBUG(dbgs() << ".. generic integer\n");
3583 OperandMatchResultTy ResTy = parseImm(Operands);
3584 return ResTy != MatchOperand_Success;
3586 case AsmToken::Percent: {
3587 // It is a symbol reference or constant expression.
3588 const MCExpr *IdVal;
3589 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3590 if (parseRelocOperand(IdVal))
3593 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3595 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3597 } // case AsmToken::Percent
3598 } // switch(getLexer().getKind())
3602 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3603 StringRef RelocStr) {
3605 // Check the type of the expression.
3606 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3607 // It's a constant, evaluate reloc value.
3609 switch (getVariantKind(RelocStr)) {
3610 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3611 // Get the 1st 16-bits.
3612 Val = MCE->getValue() & 0xffff;
3614 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3615 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3616 // 16 bits being negative.
3617 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3619 case MCSymbolRefExpr::VK_Mips_HIGHER:
3620 // Get the 3rd 16-bits.
3621 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3623 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3624 // Get the 4th 16-bits.
3625 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3628 report_fatal_error("unsupported reloc value");
3630 return MCConstantExpr::create(Val, getContext());
3633 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3634 // It's a symbol, create a symbolic expression from the symbol.
3635 const MCSymbol *Symbol = &MSRE->getSymbol();
3636 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3637 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3641 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3642 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3644 // Try to create target expression.
3645 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3646 return MipsMCExpr::create(VK, Expr, getContext());
3648 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3649 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3650 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3654 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3655 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3656 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3659 // Just return the original expression.
3663 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3665 switch (Expr->getKind()) {
3666 case MCExpr::Constant:
3668 case MCExpr::SymbolRef:
3669 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3670 case MCExpr::Binary:
3671 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3672 if (!isEvaluated(BE->getLHS()))
3674 return isEvaluated(BE->getRHS());
3677 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3678 case MCExpr::Target:
3684 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3685 MCAsmParser &Parser = getParser();
3686 Parser.Lex(); // Eat the % token.
3687 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3688 if (Tok.isNot(AsmToken::Identifier))
3691 std::string Str = Tok.getIdentifier();
3693 Parser.Lex(); // Eat the identifier.
3694 // Now make an expression from the rest of the operand.
3695 const MCExpr *IdVal;
3698 if (getLexer().getKind() == AsmToken::LParen) {
3700 Parser.Lex(); // Eat the '(' token.
3701 if (getLexer().getKind() == AsmToken::Percent) {
3702 Parser.Lex(); // Eat the % token.
3703 const AsmToken &nextTok = Parser.getTok();
3704 if (nextTok.isNot(AsmToken::Identifier))
3707 Str += nextTok.getIdentifier();
3708 Parser.Lex(); // Eat the identifier.
3709 if (getLexer().getKind() != AsmToken::LParen)
3714 if (getParser().parseParenExpression(IdVal, EndLoc))
3717 while (getLexer().getKind() == AsmToken::RParen)
3718 Parser.Lex(); // Eat the ')' token.
3721 return true; // Parenthesis must follow the relocation operand.
3723 Res = evaluateRelocExpr(IdVal, Str);
3727 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3729 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3730 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3731 if (ResTy == MatchOperand_Success) {
3732 assert(Operands.size() == 1);
3733 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3734 StartLoc = Operand.getStartLoc();
3735 EndLoc = Operand.getEndLoc();
3737 // AFAIK, we only support numeric registers and named GPR's in CFI
3739 // Don't worry about eating tokens before failing. Using an unrecognised
3740 // register is a parse error.
3741 if (Operand.isGPRAsmReg()) {
3742 // Resolve to GPR32 or GPR64 appropriately.
3743 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3746 return (RegNo == (unsigned)-1);
3749 assert(Operands.size() == 0);
3750 return (RegNo == (unsigned)-1);
3753 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3754 MCAsmParser &Parser = getParser();
3757 unsigned NumOfLParen = 0;
3759 while (getLexer().getKind() == AsmToken::LParen) {
3764 switch (getLexer().getKind()) {
3767 case AsmToken::Identifier:
3768 case AsmToken::LParen:
3769 case AsmToken::Integer:
3770 case AsmToken::Minus:
3771 case AsmToken::Plus:
3773 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3775 Result = (getParser().parseExpression(Res));
3776 while (getLexer().getKind() == AsmToken::RParen)
3779 case AsmToken::Percent:
3780 Result = parseRelocOperand(Res);
3785 MipsAsmParser::OperandMatchResultTy
3786 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3787 MCAsmParser &Parser = getParser();
3788 DEBUG(dbgs() << "parseMemOperand\n");
3789 const MCExpr *IdVal = nullptr;
3791 bool isParenExpr = false;
3792 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3793 // First operand is the offset.
3794 S = Parser.getTok().getLoc();
3796 if (getLexer().getKind() == AsmToken::LParen) {
3801 if (getLexer().getKind() != AsmToken::Dollar) {
3802 if (parseMemOffset(IdVal, isParenExpr))
3803 return MatchOperand_ParseFail;
3805 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3806 if (Tok.isNot(AsmToken::LParen)) {
3807 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3808 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3810 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3811 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3812 return MatchOperand_Success;
3814 if (Tok.is(AsmToken::EndOfStatement)) {
3816 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3818 // Zero register assumed, add a memory operand with ZERO as its base.
3819 // "Base" will be managed by k_Memory.
3820 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3823 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3824 return MatchOperand_Success;
3826 Error(Parser.getTok().getLoc(), "'(' expected");
3827 return MatchOperand_ParseFail;
3830 Parser.Lex(); // Eat the '(' token.
3833 Res = parseAnyRegister(Operands);
3834 if (Res != MatchOperand_Success)
3837 if (Parser.getTok().isNot(AsmToken::RParen)) {
3838 Error(Parser.getTok().getLoc(), "')' expected");
3839 return MatchOperand_ParseFail;
3842 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3844 Parser.Lex(); // Eat the ')' token.
3847 IdVal = MCConstantExpr::create(0, getContext());
3849 // Replace the register operand with the memory operand.
3850 std::unique_ptr<MipsOperand> op(
3851 static_cast<MipsOperand *>(Operands.back().release()));
3852 // Remove the register from the operands.
3853 // "op" will be managed by k_Memory.
3854 Operands.pop_back();
3855 // Add the memory operand.
3856 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3858 if (IdVal->evaluateAsAbsolute(Imm))
3859 IdVal = MCConstantExpr::create(Imm, getContext());
3860 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3861 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3865 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3866 return MatchOperand_Success;
3869 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3870 MCAsmParser &Parser = getParser();
3871 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3873 SMLoc S = Parser.getTok().getLoc();
3875 if (Sym->isVariable())
3876 Expr = Sym->getVariableValue();
3879 if (Expr->getKind() == MCExpr::SymbolRef) {
3880 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3881 StringRef DefSymbol = Ref->getSymbol().getName();
3882 if (DefSymbol.startswith("$")) {
3883 OperandMatchResultTy ResTy =
3884 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3885 if (ResTy == MatchOperand_Success) {
3888 } else if (ResTy == MatchOperand_ParseFail)
3889 llvm_unreachable("Should never ParseFail");
3892 } else if (Expr->getKind() == MCExpr::Constant) {
3894 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3896 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3903 MipsAsmParser::OperandMatchResultTy
3904 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3905 StringRef Identifier,
3907 int Index = matchCPURegisterName(Identifier);
3909 Operands.push_back(MipsOperand::createGPRReg(
3910 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3911 return MatchOperand_Success;
3914 Index = matchHWRegsRegisterName(Identifier);
3916 Operands.push_back(MipsOperand::createHWRegsReg(
3917 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3918 return MatchOperand_Success;
3921 Index = matchFPURegisterName(Identifier);
3923 Operands.push_back(MipsOperand::createFGRReg(
3924 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3925 return MatchOperand_Success;
3928 Index = matchFCCRegisterName(Identifier);
3930 Operands.push_back(MipsOperand::createFCCReg(
3931 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3932 return MatchOperand_Success;
3935 Index = matchACRegisterName(Identifier);
3937 Operands.push_back(MipsOperand::createACCReg(
3938 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3939 return MatchOperand_Success;
3942 Index = matchMSA128RegisterName(Identifier);
3944 Operands.push_back(MipsOperand::createMSA128Reg(
3945 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3946 return MatchOperand_Success;
3949 Index = matchMSA128CtrlRegisterName(Identifier);
3951 Operands.push_back(MipsOperand::createMSACtrlReg(
3952 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3953 return MatchOperand_Success;
3956 return MatchOperand_NoMatch;
3959 MipsAsmParser::OperandMatchResultTy
3960 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3961 MCAsmParser &Parser = getParser();
3962 auto Token = Parser.getLexer().peekTok(false);
3964 if (Token.is(AsmToken::Identifier)) {
3965 DEBUG(dbgs() << ".. identifier\n");
3966 StringRef Identifier = Token.getIdentifier();
3967 OperandMatchResultTy ResTy =
3968 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3970 } else if (Token.is(AsmToken::Integer)) {
3971 DEBUG(dbgs() << ".. integer\n");
3972 Operands.push_back(MipsOperand::createNumericReg(
3973 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3975 return MatchOperand_Success;
3978 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3980 return MatchOperand_NoMatch;
3983 MipsAsmParser::OperandMatchResultTy
3984 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3985 MCAsmParser &Parser = getParser();
3986 DEBUG(dbgs() << "parseAnyRegister\n");
3988 auto Token = Parser.getTok();
3990 SMLoc S = Token.getLoc();
3992 if (Token.isNot(AsmToken::Dollar)) {
3993 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3994 if (Token.is(AsmToken::Identifier)) {
3995 if (searchSymbolAlias(Operands))
3996 return MatchOperand_Success;
3998 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3999 return MatchOperand_NoMatch;
4001 DEBUG(dbgs() << ".. $\n");
4003 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4004 if (ResTy == MatchOperand_Success) {
4006 Parser.Lex(); // identifier
4011 MipsAsmParser::OperandMatchResultTy
4012 MipsAsmParser::parseImm(OperandVector &Operands) {
4013 MCAsmParser &Parser = getParser();
4014 switch (getLexer().getKind()) {
4016 return MatchOperand_NoMatch;
4017 case AsmToken::LParen:
4018 case AsmToken::Minus:
4019 case AsmToken::Plus:
4020 case AsmToken::Integer:
4021 case AsmToken::Tilde:
4022 case AsmToken::String:
4026 const MCExpr *IdVal;
4027 SMLoc S = Parser.getTok().getLoc();
4028 if (getParser().parseExpression(IdVal))
4029 return MatchOperand_ParseFail;
4031 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4032 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4033 return MatchOperand_Success;
4036 MipsAsmParser::OperandMatchResultTy
4037 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4038 MCAsmParser &Parser = getParser();
4039 DEBUG(dbgs() << "parseJumpTarget\n");
4041 SMLoc S = getLexer().getLoc();
4043 // Integers and expressions are acceptable
4044 OperandMatchResultTy ResTy = parseImm(Operands);
4045 if (ResTy != MatchOperand_NoMatch)
4048 // Registers are a valid target and have priority over symbols.
4049 ResTy = parseAnyRegister(Operands);
4050 if (ResTy != MatchOperand_NoMatch)
4053 const MCExpr *Expr = nullptr;
4054 if (Parser.parseExpression(Expr)) {
4055 // We have no way of knowing if a symbol was consumed so we must ParseFail
4056 return MatchOperand_ParseFail;
4059 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4060 return MatchOperand_Success;
4063 MipsAsmParser::OperandMatchResultTy
4064 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4065 MCAsmParser &Parser = getParser();
4066 const MCExpr *IdVal;
4067 // If the first token is '$' we may have register operand.
4068 if (Parser.getTok().is(AsmToken::Dollar))
4069 return MatchOperand_NoMatch;
4070 SMLoc S = Parser.getTok().getLoc();
4071 if (getParser().parseExpression(IdVal))
4072 return MatchOperand_ParseFail;
4073 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4074 assert(MCE && "Unexpected MCExpr type.");
4075 int64_t Val = MCE->getValue();
4076 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4077 Operands.push_back(MipsOperand::CreateImm(
4078 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4079 return MatchOperand_Success;
4082 MipsAsmParser::OperandMatchResultTy
4083 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4084 MCAsmParser &Parser = getParser();
4085 switch (getLexer().getKind()) {
4087 return MatchOperand_NoMatch;
4088 case AsmToken::LParen:
4089 case AsmToken::Plus:
4090 case AsmToken::Minus:
4091 case AsmToken::Integer:
4096 SMLoc S = Parser.getTok().getLoc();
4098 if (getParser().parseExpression(Expr))
4099 return MatchOperand_ParseFail;
4102 if (!Expr->evaluateAsAbsolute(Val)) {
4103 Error(S, "expected immediate value");
4104 return MatchOperand_ParseFail;
4107 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4108 // and because the CPU always adds one to the immediate field, the allowed
4109 // range becomes 1..4. We'll only check the range here and will deal
4110 // with the addition/subtraction when actually decoding/encoding
4112 if (Val < 1 || Val > 4) {
4113 Error(S, "immediate not in range (1..4)");
4114 return MatchOperand_ParseFail;
4118 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4119 return MatchOperand_Success;
4122 MipsAsmParser::OperandMatchResultTy
4123 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4124 MCAsmParser &Parser = getParser();
4125 SmallVector<unsigned, 10> Regs;
4127 unsigned PrevReg = Mips::NoRegister;
4128 bool RegRange = false;
4129 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4131 if (Parser.getTok().isNot(AsmToken::Dollar))
4132 return MatchOperand_ParseFail;
4134 SMLoc S = Parser.getTok().getLoc();
4135 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4136 SMLoc E = getLexer().getLoc();
4137 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4138 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4140 // Remove last register operand because registers from register range
4141 // should be inserted first.
4142 if (RegNo == Mips::RA) {
4143 Regs.push_back(RegNo);
4145 unsigned TmpReg = PrevReg + 1;
4146 while (TmpReg <= RegNo) {
4147 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4148 Error(E, "invalid register operand");
4149 return MatchOperand_ParseFail;
4153 Regs.push_back(TmpReg++);
4159 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4160 (RegNo != Mips::RA)) {
4161 Error(E, "$16 or $31 expected");
4162 return MatchOperand_ParseFail;
4163 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4164 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4165 Error(E, "invalid register operand");
4166 return MatchOperand_ParseFail;
4167 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4168 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4169 Error(E, "consecutive register numbers expected");
4170 return MatchOperand_ParseFail;
4173 Regs.push_back(RegNo);
4176 if (Parser.getTok().is(AsmToken::Minus))
4179 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4180 !Parser.getTok().isNot(AsmToken::Comma)) {
4181 Error(E, "',' or '-' expected");
4182 return MatchOperand_ParseFail;
4185 Lex(); // Consume comma or minus
4186 if (Parser.getTok().isNot(AsmToken::Dollar))
4192 SMLoc E = Parser.getTok().getLoc();
4193 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4194 parseMemOperand(Operands);
4195 return MatchOperand_Success;
4198 MipsAsmParser::OperandMatchResultTy
4199 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4200 MCAsmParser &Parser = getParser();
4202 SMLoc S = Parser.getTok().getLoc();
4203 if (parseAnyRegister(Operands) != MatchOperand_Success)
4204 return MatchOperand_ParseFail;
4206 SMLoc E = Parser.getTok().getLoc();
4207 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4208 unsigned Reg = Op.getGPR32Reg();
4209 Operands.pop_back();
4210 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4211 return MatchOperand_Success;
4214 MipsAsmParser::OperandMatchResultTy
4215 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4216 MCAsmParser &Parser = getParser();
4217 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4218 SmallVector<unsigned, 10> Regs;
4220 if (Parser.getTok().isNot(AsmToken::Dollar))
4221 return MatchOperand_ParseFail;
4223 SMLoc S = Parser.getTok().getLoc();
4225 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4226 return MatchOperand_ParseFail;
4228 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4229 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4230 Regs.push_back(RegNo);
4232 SMLoc E = Parser.getTok().getLoc();
4233 if (Parser.getTok().isNot(AsmToken::Comma)) {
4234 Error(E, "',' expected");
4235 return MatchOperand_ParseFail;
4241 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4242 return MatchOperand_ParseFail;
4244 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4245 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4246 Regs.push_back(RegNo);
4248 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4250 return MatchOperand_Success;
4253 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4255 MCSymbolRefExpr::VariantKind VK =
4256 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4257 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4258 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4259 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4260 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4261 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4262 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4263 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4264 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4265 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4266 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4267 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4268 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4269 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4270 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4271 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4272 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4273 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4274 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4275 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4276 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4277 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4278 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4279 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4280 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4281 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4282 .Default(MCSymbolRefExpr::VK_None);
4284 assert(VK != MCSymbolRefExpr::VK_None);
4289 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4291 /// ::= '(', register, ')'
4292 /// handle it before we iterate so we don't get tripped up by the lack of
4294 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4295 MCAsmParser &Parser = getParser();
4296 if (getLexer().is(AsmToken::LParen)) {
4298 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4300 if (parseOperand(Operands, Name)) {
4301 SMLoc Loc = getLexer().getLoc();
4302 Parser.eatToEndOfStatement();
4303 return Error(Loc, "unexpected token in argument list");
4305 if (Parser.getTok().isNot(AsmToken::RParen)) {
4306 SMLoc Loc = getLexer().getLoc();
4307 Parser.eatToEndOfStatement();
4308 return Error(Loc, "unexpected token, expected ')'");
4311 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4317 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4318 /// either one of these.
4319 /// ::= '[', register, ']'
4320 /// ::= '[', integer, ']'
4321 /// handle it before we iterate so we don't get tripped up by the lack of
4323 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4324 OperandVector &Operands) {
4325 MCAsmParser &Parser = getParser();
4326 if (getLexer().is(AsmToken::LBrac)) {
4328 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4330 if (parseOperand(Operands, Name)) {
4331 SMLoc Loc = getLexer().getLoc();
4332 Parser.eatToEndOfStatement();
4333 return Error(Loc, "unexpected token in argument list");
4335 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4336 SMLoc Loc = getLexer().getLoc();
4337 Parser.eatToEndOfStatement();
4338 return Error(Loc, "unexpected token, expected ']'");
4341 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4347 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4348 SMLoc NameLoc, OperandVector &Operands) {
4349 MCAsmParser &Parser = getParser();
4350 DEBUG(dbgs() << "ParseInstruction\n");
4352 // We have reached first instruction, module directive are now forbidden.
4353 getTargetStreamer().forbidModuleDirective();
4355 // Check if we have valid mnemonic
4356 if (!mnemonicIsValid(Name, 0)) {
4357 Parser.eatToEndOfStatement();
4358 return Error(NameLoc, "unknown instruction");
4360 // First operand in MCInst is instruction mnemonic.
4361 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4363 // Read the remaining operands.
4364 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4365 // Read the first operand.
4366 if (parseOperand(Operands, Name)) {
4367 SMLoc Loc = getLexer().getLoc();
4368 Parser.eatToEndOfStatement();
4369 return Error(Loc, "unexpected token in argument list");
4371 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4373 // AFAIK, parenthesis suffixes are never on the first operand
4375 while (getLexer().is(AsmToken::Comma)) {
4376 Parser.Lex(); // Eat the comma.
4377 // Parse and remember the operand.
4378 if (parseOperand(Operands, Name)) {
4379 SMLoc Loc = getLexer().getLoc();
4380 Parser.eatToEndOfStatement();
4381 return Error(Loc, "unexpected token in argument list");
4383 // Parse bracket and parenthesis suffixes before we iterate
4384 if (getLexer().is(AsmToken::LBrac)) {
4385 if (parseBracketSuffix(Name, Operands))
4387 } else if (getLexer().is(AsmToken::LParen) &&
4388 parseParenSuffix(Name, Operands))
4392 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4393 SMLoc Loc = getLexer().getLoc();
4394 Parser.eatToEndOfStatement();
4395 return Error(Loc, "unexpected token in argument list");
4397 Parser.Lex(); // Consume the EndOfStatement.
4401 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4402 MCAsmParser &Parser = getParser();
4403 SMLoc Loc = getLexer().getLoc();
4404 Parser.eatToEndOfStatement();
4405 return Error(Loc, ErrorMsg);
4408 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4409 return Error(Loc, ErrorMsg);
4412 bool MipsAsmParser::parseSetNoAtDirective() {
4413 MCAsmParser &Parser = getParser();
4414 // Line should look like: ".set noat".
4416 // Set the $at register to $0.
4417 AssemblerOptions.back()->setATRegIndex(0);
4419 Parser.Lex(); // Eat "noat".
4421 // If this is not the end of the statement, report an error.
4422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4423 reportParseError("unexpected token, expected end of statement");
4427 getTargetStreamer().emitDirectiveSetNoAt();
4428 Parser.Lex(); // Consume the EndOfStatement.
4432 bool MipsAsmParser::parseSetAtDirective() {
4433 // Line can be: ".set at", which sets $at to $1
4434 // or ".set at=$reg", which sets $at to $reg.
4435 MCAsmParser &Parser = getParser();
4436 Parser.Lex(); // Eat "at".
4438 if (getLexer().is(AsmToken::EndOfStatement)) {
4439 // No register was specified, so we set $at to $1.
4440 AssemblerOptions.back()->setATRegIndex(1);
4442 getTargetStreamer().emitDirectiveSetAt();
4443 Parser.Lex(); // Consume the EndOfStatement.
4447 if (getLexer().isNot(AsmToken::Equal)) {
4448 reportParseError("unexpected token, expected equals sign");
4451 Parser.Lex(); // Eat "=".
4453 if (getLexer().isNot(AsmToken::Dollar)) {
4454 if (getLexer().is(AsmToken::EndOfStatement)) {
4455 reportParseError("no register specified");
4458 reportParseError("unexpected token, expected dollar sign '$'");
4462 Parser.Lex(); // Eat "$".
4464 // Find out what "reg" is.
4466 const AsmToken &Reg = Parser.getTok();
4467 if (Reg.is(AsmToken::Identifier)) {
4468 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4469 } else if (Reg.is(AsmToken::Integer)) {
4470 AtRegNo = Reg.getIntVal();
4472 reportParseError("unexpected token, expected identifier or integer");
4476 // Check if $reg is a valid register. If it is, set $at to $reg.
4477 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4478 reportParseError("invalid register");
4481 Parser.Lex(); // Eat "reg".
4483 // If this is not the end of the statement, report an error.
4484 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4485 reportParseError("unexpected token, expected end of statement");
4489 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4491 Parser.Lex(); // Consume the EndOfStatement.
4495 bool MipsAsmParser::parseSetReorderDirective() {
4496 MCAsmParser &Parser = getParser();
4498 // If this is not the end of the statement, report an error.
4499 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4500 reportParseError("unexpected token, expected end of statement");
4503 AssemblerOptions.back()->setReorder();
4504 getTargetStreamer().emitDirectiveSetReorder();
4505 Parser.Lex(); // Consume the EndOfStatement.
4509 bool MipsAsmParser::parseSetNoReorderDirective() {
4510 MCAsmParser &Parser = getParser();
4512 // If this is not the end of the statement, report an error.
4513 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4514 reportParseError("unexpected token, expected end of statement");
4517 AssemblerOptions.back()->setNoReorder();
4518 getTargetStreamer().emitDirectiveSetNoReorder();
4519 Parser.Lex(); // Consume the EndOfStatement.
4523 bool MipsAsmParser::parseSetMacroDirective() {
4524 MCAsmParser &Parser = getParser();
4526 // If this is not the end of the statement, report an error.
4527 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4528 reportParseError("unexpected token, expected end of statement");
4531 AssemblerOptions.back()->setMacro();
4532 getTargetStreamer().emitDirectiveSetMacro();
4533 Parser.Lex(); // Consume the EndOfStatement.
4537 bool MipsAsmParser::parseSetNoMacroDirective() {
4538 MCAsmParser &Parser = getParser();
4540 // If this is not the end of the statement, report an error.
4541 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4542 reportParseError("unexpected token, expected end of statement");
4545 if (AssemblerOptions.back()->isReorder()) {
4546 reportParseError("`noreorder' must be set before `nomacro'");
4549 AssemblerOptions.back()->setNoMacro();
4550 getTargetStreamer().emitDirectiveSetNoMacro();
4551 Parser.Lex(); // Consume the EndOfStatement.
4555 bool MipsAsmParser::parseSetMsaDirective() {
4556 MCAsmParser &Parser = getParser();
4559 // If this is not the end of the statement, report an error.
4560 if (getLexer().isNot(AsmToken::EndOfStatement))
4561 return reportParseError("unexpected token, expected end of statement");
4563 setFeatureBits(Mips::FeatureMSA, "msa");
4564 getTargetStreamer().emitDirectiveSetMsa();
4568 bool MipsAsmParser::parseSetNoMsaDirective() {
4569 MCAsmParser &Parser = getParser();
4572 // If this is not the end of the statement, report an error.
4573 if (getLexer().isNot(AsmToken::EndOfStatement))
4574 return reportParseError("unexpected token, expected end of statement");
4576 clearFeatureBits(Mips::FeatureMSA, "msa");
4577 getTargetStreamer().emitDirectiveSetNoMsa();
4581 bool MipsAsmParser::parseSetNoDspDirective() {
4582 MCAsmParser &Parser = getParser();
4583 Parser.Lex(); // Eat "nodsp".
4585 // If this is not the end of the statement, report an error.
4586 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4587 reportParseError("unexpected token, expected end of statement");
4591 clearFeatureBits(Mips::FeatureDSP, "dsp");
4592 getTargetStreamer().emitDirectiveSetNoDsp();
4596 bool MipsAsmParser::parseSetMips16Directive() {
4597 MCAsmParser &Parser = getParser();
4598 Parser.Lex(); // Eat "mips16".
4600 // If this is not the end of the statement, report an error.
4601 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4602 reportParseError("unexpected token, expected end of statement");
4606 setFeatureBits(Mips::FeatureMips16, "mips16");
4607 getTargetStreamer().emitDirectiveSetMips16();
4608 Parser.Lex(); // Consume the EndOfStatement.
4612 bool MipsAsmParser::parseSetNoMips16Directive() {
4613 MCAsmParser &Parser = getParser();
4614 Parser.Lex(); // Eat "nomips16".
4616 // If this is not the end of the statement, report an error.
4617 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4618 reportParseError("unexpected token, expected end of statement");
4622 clearFeatureBits(Mips::FeatureMips16, "mips16");
4623 getTargetStreamer().emitDirectiveSetNoMips16();
4624 Parser.Lex(); // Consume the EndOfStatement.
4628 bool MipsAsmParser::parseSetFpDirective() {
4629 MCAsmParser &Parser = getParser();
4630 MipsABIFlagsSection::FpABIKind FpAbiVal;
4631 // Line can be: .set fp=32
4634 Parser.Lex(); // Eat fp token
4635 AsmToken Tok = Parser.getTok();
4636 if (Tok.isNot(AsmToken::Equal)) {
4637 reportParseError("unexpected token, expected equals sign '='");
4640 Parser.Lex(); // Eat '=' token.
4641 Tok = Parser.getTok();
4643 if (!parseFpABIValue(FpAbiVal, ".set"))
4646 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4647 reportParseError("unexpected token, expected end of statement");
4650 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4651 Parser.Lex(); // Consume the EndOfStatement.
4655 bool MipsAsmParser::parseSetOddSPRegDirective() {
4656 MCAsmParser &Parser = getParser();
4658 Parser.Lex(); // Eat "oddspreg".
4659 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4660 reportParseError("unexpected token, expected end of statement");
4664 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4665 getTargetStreamer().emitDirectiveSetOddSPReg();
4669 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4670 MCAsmParser &Parser = getParser();
4672 Parser.Lex(); // Eat "nooddspreg".
4673 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4674 reportParseError("unexpected token, expected end of statement");
4678 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4679 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4683 bool MipsAsmParser::parseSetPopDirective() {
4684 MCAsmParser &Parser = getParser();
4685 SMLoc Loc = getLexer().getLoc();
4688 if (getLexer().isNot(AsmToken::EndOfStatement))
4689 return reportParseError("unexpected token, expected end of statement");
4691 // Always keep an element on the options "stack" to prevent the user
4692 // from changing the initial options. This is how we remember them.
4693 if (AssemblerOptions.size() == 2)
4694 return reportParseError(Loc, ".set pop with no .set push");
4696 AssemblerOptions.pop_back();
4697 setAvailableFeatures(
4698 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4699 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4701 getTargetStreamer().emitDirectiveSetPop();
4705 bool MipsAsmParser::parseSetPushDirective() {
4706 MCAsmParser &Parser = getParser();
4708 if (getLexer().isNot(AsmToken::EndOfStatement))
4709 return reportParseError("unexpected token, expected end of statement");
4711 // Create a copy of the current assembler options environment and push it.
4712 AssemblerOptions.push_back(
4713 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4715 getTargetStreamer().emitDirectiveSetPush();
4719 bool MipsAsmParser::parseSetSoftFloatDirective() {
4720 MCAsmParser &Parser = getParser();
4722 if (getLexer().isNot(AsmToken::EndOfStatement))
4723 return reportParseError("unexpected token, expected end of statement");
4725 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4726 getTargetStreamer().emitDirectiveSetSoftFloat();
4730 bool MipsAsmParser::parseSetHardFloatDirective() {
4731 MCAsmParser &Parser = getParser();
4733 if (getLexer().isNot(AsmToken::EndOfStatement))
4734 return reportParseError("unexpected token, expected end of statement");
4736 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4737 getTargetStreamer().emitDirectiveSetHardFloat();
4741 bool MipsAsmParser::parseSetAssignment() {
4743 const MCExpr *Value;
4744 MCAsmParser &Parser = getParser();
4746 if (Parser.parseIdentifier(Name))
4747 reportParseError("expected identifier after .set");
4749 if (getLexer().isNot(AsmToken::Comma))
4750 return reportParseError("unexpected token, expected comma");
4753 if (Parser.parseExpression(Value))
4754 return reportParseError("expected valid expression after comma");
4756 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4757 Sym->setVariableValue(Value);
4762 bool MipsAsmParser::parseSetMips0Directive() {
4763 MCAsmParser &Parser = getParser();
4765 if (getLexer().isNot(AsmToken::EndOfStatement))
4766 return reportParseError("unexpected token, expected end of statement");
4768 // Reset assembler options to their initial values.
4769 setAvailableFeatures(
4770 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4771 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4772 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4774 getTargetStreamer().emitDirectiveSetMips0();
4778 bool MipsAsmParser::parseSetArchDirective() {
4779 MCAsmParser &Parser = getParser();
4781 if (getLexer().isNot(AsmToken::Equal))
4782 return reportParseError("unexpected token, expected equals sign");
4786 if (Parser.parseIdentifier(Arch))
4787 return reportParseError("expected arch identifier");
4789 StringRef ArchFeatureName =
4790 StringSwitch<StringRef>(Arch)
4791 .Case("mips1", "mips1")
4792 .Case("mips2", "mips2")
4793 .Case("mips3", "mips3")
4794 .Case("mips4", "mips4")
4795 .Case("mips5", "mips5")
4796 .Case("mips32", "mips32")
4797 .Case("mips32r2", "mips32r2")
4798 .Case("mips32r3", "mips32r3")
4799 .Case("mips32r5", "mips32r5")
4800 .Case("mips32r6", "mips32r6")
4801 .Case("mips64", "mips64")
4802 .Case("mips64r2", "mips64r2")
4803 .Case("mips64r3", "mips64r3")
4804 .Case("mips64r5", "mips64r5")
4805 .Case("mips64r6", "mips64r6")
4806 .Case("cnmips", "cnmips")
4807 .Case("r4000", "mips3") // This is an implementation of Mips3.
4810 if (ArchFeatureName.empty())
4811 return reportParseError("unsupported architecture");
4813 selectArch(ArchFeatureName);
4814 getTargetStreamer().emitDirectiveSetArch(Arch);
4818 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4819 MCAsmParser &Parser = getParser();
4821 if (getLexer().isNot(AsmToken::EndOfStatement))
4822 return reportParseError("unexpected token, expected end of statement");
4826 llvm_unreachable("Unimplemented feature");
4827 case Mips::FeatureDSP:
4828 setFeatureBits(Mips::FeatureDSP, "dsp");
4829 getTargetStreamer().emitDirectiveSetDsp();
4831 case Mips::FeatureMicroMips:
4832 getTargetStreamer().emitDirectiveSetMicroMips();
4834 case Mips::FeatureMips1:
4835 selectArch("mips1");
4836 getTargetStreamer().emitDirectiveSetMips1();
4838 case Mips::FeatureMips2:
4839 selectArch("mips2");
4840 getTargetStreamer().emitDirectiveSetMips2();
4842 case Mips::FeatureMips3:
4843 selectArch("mips3");
4844 getTargetStreamer().emitDirectiveSetMips3();
4846 case Mips::FeatureMips4:
4847 selectArch("mips4");
4848 getTargetStreamer().emitDirectiveSetMips4();
4850 case Mips::FeatureMips5:
4851 selectArch("mips5");
4852 getTargetStreamer().emitDirectiveSetMips5();
4854 case Mips::FeatureMips32:
4855 selectArch("mips32");
4856 getTargetStreamer().emitDirectiveSetMips32();
4858 case Mips::FeatureMips32r2:
4859 selectArch("mips32r2");
4860 getTargetStreamer().emitDirectiveSetMips32R2();
4862 case Mips::FeatureMips32r3:
4863 selectArch("mips32r3");
4864 getTargetStreamer().emitDirectiveSetMips32R3();
4866 case Mips::FeatureMips32r5:
4867 selectArch("mips32r5");
4868 getTargetStreamer().emitDirectiveSetMips32R5();
4870 case Mips::FeatureMips32r6:
4871 selectArch("mips32r6");
4872 getTargetStreamer().emitDirectiveSetMips32R6();
4874 case Mips::FeatureMips64:
4875 selectArch("mips64");
4876 getTargetStreamer().emitDirectiveSetMips64();
4878 case Mips::FeatureMips64r2:
4879 selectArch("mips64r2");
4880 getTargetStreamer().emitDirectiveSetMips64R2();
4882 case Mips::FeatureMips64r3:
4883 selectArch("mips64r3");
4884 getTargetStreamer().emitDirectiveSetMips64R3();
4886 case Mips::FeatureMips64r5:
4887 selectArch("mips64r5");
4888 getTargetStreamer().emitDirectiveSetMips64R5();
4890 case Mips::FeatureMips64r6:
4891 selectArch("mips64r6");
4892 getTargetStreamer().emitDirectiveSetMips64R6();
4898 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4899 MCAsmParser &Parser = getParser();
4900 if (getLexer().isNot(AsmToken::Comma)) {
4901 SMLoc Loc = getLexer().getLoc();
4902 Parser.eatToEndOfStatement();
4903 return Error(Loc, ErrorStr);
4906 Parser.Lex(); // Eat the comma.
4910 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4911 // In this class, it is only used for .cprestore.
4912 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4913 // MipsTargetELFStreamer and MipsAsmParser.
4914 bool MipsAsmParser::isPicAndNotNxxAbi() {
4915 return inPicMode() && !(isABI_N32() || isABI_N64());
4918 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4919 if (AssemblerOptions.back()->isReorder())
4920 Warning(Loc, ".cpload should be inside a noreorder section");
4922 if (inMips16Mode()) {
4923 reportParseError(".cpload is not supported in Mips16 mode");
4927 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4928 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4929 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4930 reportParseError("expected register containing function address");
4934 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4935 if (!RegOpnd.isGPRAsmReg()) {
4936 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4940 // If this is not the end of the statement, report an error.
4941 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4942 reportParseError("unexpected token, expected end of statement");
4946 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4950 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4951 MCAsmParser &Parser = getParser();
4953 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4954 // is used in non-PIC mode.
4956 if (inMips16Mode()) {
4957 reportParseError(".cprestore is not supported in Mips16 mode");
4961 // Get the stack offset value.
4962 const MCExpr *StackOffset;
4963 int64_t StackOffsetVal;
4964 if (Parser.parseExpression(StackOffset)) {
4965 reportParseError("expected stack offset value");
4969 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4970 reportParseError("stack offset is not an absolute expression");
4974 if (StackOffsetVal < 0) {
4975 Warning(Loc, ".cprestore with negative stack offset has no effect");
4976 IsCpRestoreSet = false;
4978 IsCpRestoreSet = true;
4979 CpRestoreOffset = StackOffsetVal;
4982 // If this is not the end of the statement, report an error.
4983 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4984 reportParseError("unexpected token, expected end of statement");
4988 // Store the $gp on the stack.
4989 SmallVector<MCInst, 3> StoreInsts;
4990 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
4993 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
4994 Parser.Lex(); // Consume the EndOfStatement.
4998 bool MipsAsmParser::parseDirectiveCPSetup() {
4999 MCAsmParser &Parser = getParser();
5002 bool SaveIsReg = true;
5004 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5005 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5006 if (ResTy == MatchOperand_NoMatch) {
5007 reportParseError("expected register containing function address");
5008 Parser.eatToEndOfStatement();
5012 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5013 if (!FuncRegOpnd.isGPRAsmReg()) {
5014 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5015 Parser.eatToEndOfStatement();
5019 FuncReg = FuncRegOpnd.getGPR32Reg();
5022 if (!eatComma("unexpected token, expected comma"))
5025 ResTy = parseAnyRegister(TmpReg);
5026 if (ResTy == MatchOperand_NoMatch) {
5027 const MCExpr *OffsetExpr;
5029 SMLoc ExprLoc = getLexer().getLoc();
5031 if (Parser.parseExpression(OffsetExpr) ||
5032 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5033 reportParseError(ExprLoc, "expected save register or stack offset");
5034 Parser.eatToEndOfStatement();
5041 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5042 if (!SaveOpnd.isGPRAsmReg()) {
5043 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5044 Parser.eatToEndOfStatement();
5047 Save = SaveOpnd.getGPR32Reg();
5050 if (!eatComma("unexpected token, expected comma"))
5054 if (Parser.parseExpression(Expr)) {
5055 reportParseError("expected expression");
5059 if (Expr->getKind() != MCExpr::SymbolRef) {
5060 reportParseError("expected symbol");
5063 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5065 CpSaveLocation = Save;
5066 CpSaveLocationIsRegister = SaveIsReg;
5068 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5073 bool MipsAsmParser::parseDirectiveCPReturn() {
5074 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5075 CpSaveLocationIsRegister);
5079 bool MipsAsmParser::parseDirectiveNaN() {
5080 MCAsmParser &Parser = getParser();
5081 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5082 const AsmToken &Tok = Parser.getTok();
5084 if (Tok.getString() == "2008") {
5086 getTargetStreamer().emitDirectiveNaN2008();
5088 } else if (Tok.getString() == "legacy") {
5090 getTargetStreamer().emitDirectiveNaNLegacy();
5094 // If we don't recognize the option passed to the .nan
5095 // directive (e.g. no option or unknown option), emit an error.
5096 reportParseError("invalid option in .nan directive");
5100 bool MipsAsmParser::parseDirectiveSet() {
5101 MCAsmParser &Parser = getParser();
5102 // Get the next token.
5103 const AsmToken &Tok = Parser.getTok();
5105 if (Tok.getString() == "noat") {
5106 return parseSetNoAtDirective();
5107 } else if (Tok.getString() == "at") {
5108 return parseSetAtDirective();
5109 } else if (Tok.getString() == "arch") {
5110 return parseSetArchDirective();
5111 } else if (Tok.getString() == "fp") {
5112 return parseSetFpDirective();
5113 } else if (Tok.getString() == "oddspreg") {
5114 return parseSetOddSPRegDirective();
5115 } else if (Tok.getString() == "nooddspreg") {
5116 return parseSetNoOddSPRegDirective();
5117 } else if (Tok.getString() == "pop") {
5118 return parseSetPopDirective();
5119 } else if (Tok.getString() == "push") {
5120 return parseSetPushDirective();
5121 } else if (Tok.getString() == "reorder") {
5122 return parseSetReorderDirective();
5123 } else if (Tok.getString() == "noreorder") {
5124 return parseSetNoReorderDirective();
5125 } else if (Tok.getString() == "macro") {
5126 return parseSetMacroDirective();
5127 } else if (Tok.getString() == "nomacro") {
5128 return parseSetNoMacroDirective();
5129 } else if (Tok.getString() == "mips16") {
5130 return parseSetMips16Directive();
5131 } else if (Tok.getString() == "nomips16") {
5132 return parseSetNoMips16Directive();
5133 } else if (Tok.getString() == "nomicromips") {
5134 getTargetStreamer().emitDirectiveSetNoMicroMips();
5135 Parser.eatToEndOfStatement();
5137 } else if (Tok.getString() == "micromips") {
5138 return parseSetFeature(Mips::FeatureMicroMips);
5139 } else if (Tok.getString() == "mips0") {
5140 return parseSetMips0Directive();
5141 } else if (Tok.getString() == "mips1") {
5142 return parseSetFeature(Mips::FeatureMips1);
5143 } else if (Tok.getString() == "mips2") {
5144 return parseSetFeature(Mips::FeatureMips2);
5145 } else if (Tok.getString() == "mips3") {
5146 return parseSetFeature(Mips::FeatureMips3);
5147 } else if (Tok.getString() == "mips4") {
5148 return parseSetFeature(Mips::FeatureMips4);
5149 } else if (Tok.getString() == "mips5") {
5150 return parseSetFeature(Mips::FeatureMips5);
5151 } else if (Tok.getString() == "mips32") {
5152 return parseSetFeature(Mips::FeatureMips32);
5153 } else if (Tok.getString() == "mips32r2") {
5154 return parseSetFeature(Mips::FeatureMips32r2);
5155 } else if (Tok.getString() == "mips32r3") {
5156 return parseSetFeature(Mips::FeatureMips32r3);
5157 } else if (Tok.getString() == "mips32r5") {
5158 return parseSetFeature(Mips::FeatureMips32r5);
5159 } else if (Tok.getString() == "mips32r6") {
5160 return parseSetFeature(Mips::FeatureMips32r6);
5161 } else if (Tok.getString() == "mips64") {
5162 return parseSetFeature(Mips::FeatureMips64);
5163 } else if (Tok.getString() == "mips64r2") {
5164 return parseSetFeature(Mips::FeatureMips64r2);
5165 } else if (Tok.getString() == "mips64r3") {
5166 return parseSetFeature(Mips::FeatureMips64r3);
5167 } else if (Tok.getString() == "mips64r5") {
5168 return parseSetFeature(Mips::FeatureMips64r5);
5169 } else if (Tok.getString() == "mips64r6") {
5170 return parseSetFeature(Mips::FeatureMips64r6);
5171 } else if (Tok.getString() == "dsp") {
5172 return parseSetFeature(Mips::FeatureDSP);
5173 } else if (Tok.getString() == "nodsp") {
5174 return parseSetNoDspDirective();
5175 } else if (Tok.getString() == "msa") {
5176 return parseSetMsaDirective();
5177 } else if (Tok.getString() == "nomsa") {
5178 return parseSetNoMsaDirective();
5179 } else if (Tok.getString() == "softfloat") {
5180 return parseSetSoftFloatDirective();
5181 } else if (Tok.getString() == "hardfloat") {
5182 return parseSetHardFloatDirective();
5184 // It is just an identifier, look for an assignment.
5185 parseSetAssignment();
5192 /// parseDataDirective
5193 /// ::= .word [ expression (, expression)* ]
5194 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5195 MCAsmParser &Parser = getParser();
5196 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5198 const MCExpr *Value;
5199 if (getParser().parseExpression(Value))
5202 getParser().getStreamer().EmitValue(Value, Size);
5204 if (getLexer().is(AsmToken::EndOfStatement))
5207 if (getLexer().isNot(AsmToken::Comma))
5208 return Error(L, "unexpected token, expected comma");
5217 /// parseDirectiveGpWord
5218 /// ::= .gpword local_sym
5219 bool MipsAsmParser::parseDirectiveGpWord() {
5220 MCAsmParser &Parser = getParser();
5221 const MCExpr *Value;
5222 // EmitGPRel32Value requires an expression, so we are using base class
5223 // method to evaluate the expression.
5224 if (getParser().parseExpression(Value))
5226 getParser().getStreamer().EmitGPRel32Value(Value);
5228 if (getLexer().isNot(AsmToken::EndOfStatement))
5229 return Error(getLexer().getLoc(),
5230 "unexpected token, expected end of statement");
5231 Parser.Lex(); // Eat EndOfStatement token.
5235 /// parseDirectiveGpDWord
5236 /// ::= .gpdword local_sym
5237 bool MipsAsmParser::parseDirectiveGpDWord() {
5238 MCAsmParser &Parser = getParser();
5239 const MCExpr *Value;
5240 // EmitGPRel64Value requires an expression, so we are using base class
5241 // method to evaluate the expression.
5242 if (getParser().parseExpression(Value))
5244 getParser().getStreamer().EmitGPRel64Value(Value);
5246 if (getLexer().isNot(AsmToken::EndOfStatement))
5247 return Error(getLexer().getLoc(),
5248 "unexpected token, expected end of statement");
5249 Parser.Lex(); // Eat EndOfStatement token.
5253 bool MipsAsmParser::parseDirectiveOption() {
5254 MCAsmParser &Parser = getParser();
5255 // Get the option token.
5256 AsmToken Tok = Parser.getTok();
5257 // At the moment only identifiers are supported.
5258 if (Tok.isNot(AsmToken::Identifier)) {
5259 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5260 Parser.eatToEndOfStatement();
5264 StringRef Option = Tok.getIdentifier();
5266 if (Option == "pic0") {
5267 // MipsAsmParser needs to know if the current PIC mode changes.
5268 IsPicEnabled = false;
5270 getTargetStreamer().emitDirectiveOptionPic0();
5272 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5273 Error(Parser.getTok().getLoc(),
5274 "unexpected token, expected end of statement");
5275 Parser.eatToEndOfStatement();
5280 if (Option == "pic2") {
5281 // MipsAsmParser needs to know if the current PIC mode changes.
5282 IsPicEnabled = true;
5284 getTargetStreamer().emitDirectiveOptionPic2();
5286 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5287 Error(Parser.getTok().getLoc(),
5288 "unexpected token, expected end of statement");
5289 Parser.eatToEndOfStatement();
5295 Warning(Parser.getTok().getLoc(),
5296 "unknown option, expected 'pic0' or 'pic2'");
5297 Parser.eatToEndOfStatement();
5301 /// parseInsnDirective
5303 bool MipsAsmParser::parseInsnDirective() {
5304 // If this is not the end of the statement, report an error.
5305 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5306 reportParseError("unexpected token, expected end of statement");
5310 // The actual label marking happens in
5311 // MipsELFStreamer::createPendingLabelRelocs().
5312 getTargetStreamer().emitDirectiveInsn();
5314 getParser().Lex(); // Eat EndOfStatement token.
5318 /// parseDirectiveModule
5319 /// ::= .module oddspreg
5320 /// ::= .module nooddspreg
5321 /// ::= .module fp=value
5322 /// ::= .module softfloat
5323 /// ::= .module hardfloat
5324 bool MipsAsmParser::parseDirectiveModule() {
5325 MCAsmParser &Parser = getParser();
5326 MCAsmLexer &Lexer = getLexer();
5327 SMLoc L = Lexer.getLoc();
5329 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5330 // TODO : get a better message.
5331 reportParseError(".module directive must appear before any code");
5336 if (Parser.parseIdentifier(Option)) {
5337 reportParseError("expected .module option identifier");
5341 if (Option == "oddspreg") {
5342 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5344 // Synchronize the abiflags information with the FeatureBits information we
5346 getTargetStreamer().updateABIInfo(*this);
5348 // If printing assembly, use the recently updated abiflags information.
5349 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5350 // emitted at the end).
5351 getTargetStreamer().emitDirectiveModuleOddSPReg();
5353 // If this is not the end of the statement, report an error.
5354 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5355 reportParseError("unexpected token, expected end of statement");
5359 return false; // parseDirectiveModule has finished successfully.
5360 } else if (Option == "nooddspreg") {
5362 Error(L, "'.module nooddspreg' requires the O32 ABI");
5366 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5368 // Synchronize the abiflags information with the FeatureBits information we
5370 getTargetStreamer().updateABIInfo(*this);
5372 // If printing assembly, use the recently updated abiflags information.
5373 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5374 // emitted at the end).
5375 getTargetStreamer().emitDirectiveModuleOddSPReg();
5377 // If this is not the end of the statement, report an error.
5378 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5379 reportParseError("unexpected token, expected end of statement");
5383 return false; // parseDirectiveModule has finished successfully.
5384 } else if (Option == "fp") {
5385 return parseDirectiveModuleFP();
5386 } else if (Option == "softfloat") {
5387 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5389 // Synchronize the ABI Flags information with the FeatureBits information we
5391 getTargetStreamer().updateABIInfo(*this);
5393 // If printing assembly, use the recently updated ABI Flags information.
5394 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5396 getTargetStreamer().emitDirectiveModuleSoftFloat();
5398 // If this is not the end of the statement, report an error.
5399 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5400 reportParseError("unexpected token, expected end of statement");
5404 return false; // parseDirectiveModule has finished successfully.
5405 } else if (Option == "hardfloat") {
5406 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5408 // Synchronize the ABI Flags information with the FeatureBits information we
5410 getTargetStreamer().updateABIInfo(*this);
5412 // If printing assembly, use the recently updated ABI Flags information.
5413 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5415 getTargetStreamer().emitDirectiveModuleHardFloat();
5417 // If this is not the end of the statement, report an error.
5418 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5419 reportParseError("unexpected token, expected end of statement");
5423 return false; // parseDirectiveModule has finished successfully.
5425 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5429 /// parseDirectiveModuleFP
5433 bool MipsAsmParser::parseDirectiveModuleFP() {
5434 MCAsmParser &Parser = getParser();
5435 MCAsmLexer &Lexer = getLexer();
5437 if (Lexer.isNot(AsmToken::Equal)) {
5438 reportParseError("unexpected token, expected equals sign '='");
5441 Parser.Lex(); // Eat '=' token.
5443 MipsABIFlagsSection::FpABIKind FpABI;
5444 if (!parseFpABIValue(FpABI, ".module"))
5447 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5448 reportParseError("unexpected token, expected end of statement");
5452 // Synchronize the abiflags information with the FeatureBits information we
5454 getTargetStreamer().updateABIInfo(*this);
5456 // If printing assembly, use the recently updated abiflags information.
5457 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5458 // emitted at the end).
5459 getTargetStreamer().emitDirectiveModuleFP();
5461 Parser.Lex(); // Consume the EndOfStatement.
5465 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5466 StringRef Directive) {
5467 MCAsmParser &Parser = getParser();
5468 MCAsmLexer &Lexer = getLexer();
5469 bool ModuleLevelOptions = Directive == ".module";
5471 if (Lexer.is(AsmToken::Identifier)) {
5472 StringRef Value = Parser.getTok().getString();
5475 if (Value != "xx") {
5476 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5481 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5485 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5486 if (ModuleLevelOptions) {
5487 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5488 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5490 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5491 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5496 if (Lexer.is(AsmToken::Integer)) {
5497 unsigned Value = Parser.getTok().getIntVal();
5500 if (Value != 32 && Value != 64) {
5501 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5507 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5511 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5512 if (ModuleLevelOptions) {
5513 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5514 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5516 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5517 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5520 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5521 if (ModuleLevelOptions) {
5522 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5523 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5525 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5526 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5536 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5537 MCAsmParser &Parser = getParser();
5538 StringRef IDVal = DirectiveID.getString();
5540 if (IDVal == ".cpload")
5541 return parseDirectiveCpLoad(DirectiveID.getLoc());
5542 if (IDVal == ".cprestore")
5543 return parseDirectiveCpRestore(DirectiveID.getLoc());
5544 if (IDVal == ".dword") {
5545 parseDataDirective(8, DirectiveID.getLoc());
5548 if (IDVal == ".ent") {
5549 StringRef SymbolName;
5551 if (Parser.parseIdentifier(SymbolName)) {
5552 reportParseError("expected identifier after .ent");
5556 // There's an undocumented extension that allows an integer to
5557 // follow the name of the procedure which AFAICS is ignored by GAS.
5558 // Example: .ent foo,2
5559 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5560 if (getLexer().isNot(AsmToken::Comma)) {
5561 // Even though we accept this undocumented extension for compatibility
5562 // reasons, the additional integer argument does not actually change
5563 // the behaviour of the '.ent' directive, so we would like to discourage
5564 // its use. We do this by not referring to the extended version in
5565 // error messages which are not directly related to its use.
5566 reportParseError("unexpected token, expected end of statement");
5569 Parser.Lex(); // Eat the comma.
5570 const MCExpr *DummyNumber;
5571 int64_t DummyNumberVal;
5572 // If the user was explicitly trying to use the extended version,
5573 // we still give helpful extension-related error messages.
5574 if (Parser.parseExpression(DummyNumber)) {
5575 reportParseError("expected number after comma");
5578 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5579 reportParseError("expected an absolute expression after comma");
5584 // If this is not the end of the statement, report an error.
5585 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5586 reportParseError("unexpected token, expected end of statement");
5590 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5592 getTargetStreamer().emitDirectiveEnt(*Sym);
5594 IsCpRestoreSet = false;
5598 if (IDVal == ".end") {
5599 StringRef SymbolName;
5601 if (Parser.parseIdentifier(SymbolName)) {
5602 reportParseError("expected identifier after .end");
5606 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5607 reportParseError("unexpected token, expected end of statement");
5611 if (CurrentFn == nullptr) {
5612 reportParseError(".end used without .ent");
5616 if ((SymbolName != CurrentFn->getName())) {
5617 reportParseError(".end symbol does not match .ent symbol");
5621 getTargetStreamer().emitDirectiveEnd(SymbolName);
5622 CurrentFn = nullptr;
5623 IsCpRestoreSet = false;
5627 if (IDVal == ".frame") {
5628 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5629 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5630 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5631 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5632 reportParseError("expected stack register");
5636 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5637 if (!StackRegOpnd.isGPRAsmReg()) {
5638 reportParseError(StackRegOpnd.getStartLoc(),
5639 "expected general purpose register");
5642 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5644 if (Parser.getTok().is(AsmToken::Comma))
5647 reportParseError("unexpected token, expected comma");
5651 // Parse the frame size.
5652 const MCExpr *FrameSize;
5653 int64_t FrameSizeVal;
5655 if (Parser.parseExpression(FrameSize)) {
5656 reportParseError("expected frame size value");
5660 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5661 reportParseError("frame size not an absolute expression");
5665 if (Parser.getTok().is(AsmToken::Comma))
5668 reportParseError("unexpected token, expected comma");
5672 // Parse the return register.
5674 ResTy = parseAnyRegister(TmpReg);
5675 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5676 reportParseError("expected return register");
5680 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5681 if (!ReturnRegOpnd.isGPRAsmReg()) {
5682 reportParseError(ReturnRegOpnd.getStartLoc(),
5683 "expected general purpose register");
5687 // If this is not the end of the statement, report an error.
5688 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5689 reportParseError("unexpected token, expected end of statement");
5693 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5694 ReturnRegOpnd.getGPR32Reg());
5695 IsCpRestoreSet = false;
5699 if (IDVal == ".set") {
5700 return parseDirectiveSet();
5703 if (IDVal == ".mask" || IDVal == ".fmask") {
5704 // .mask bitmask, frame_offset
5705 // bitmask: One bit for each register used.
5706 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5707 // first register is expected to be saved.
5709 // .mask 0x80000000, -4
5710 // .fmask 0x80000000, -4
5713 // Parse the bitmask
5714 const MCExpr *BitMask;
5717 if (Parser.parseExpression(BitMask)) {
5718 reportParseError("expected bitmask value");
5722 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5723 reportParseError("bitmask not an absolute expression");
5727 if (Parser.getTok().is(AsmToken::Comma))
5730 reportParseError("unexpected token, expected comma");
5734 // Parse the frame_offset
5735 const MCExpr *FrameOffset;
5736 int64_t FrameOffsetVal;
5738 if (Parser.parseExpression(FrameOffset)) {
5739 reportParseError("expected frame offset value");
5743 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5744 reportParseError("frame offset not an absolute expression");
5748 // If this is not the end of the statement, report an error.
5749 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5750 reportParseError("unexpected token, expected end of statement");
5754 if (IDVal == ".mask")
5755 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5757 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5761 if (IDVal == ".nan")
5762 return parseDirectiveNaN();
5764 if (IDVal == ".gpword") {
5765 parseDirectiveGpWord();
5769 if (IDVal == ".gpdword") {
5770 parseDirectiveGpDWord();
5774 if (IDVal == ".word") {
5775 parseDataDirective(4, DirectiveID.getLoc());
5779 if (IDVal == ".option")
5780 return parseDirectiveOption();
5782 if (IDVal == ".abicalls") {
5783 getTargetStreamer().emitDirectiveAbiCalls();
5784 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5785 Error(Parser.getTok().getLoc(),
5786 "unexpected token, expected end of statement");
5788 Parser.eatToEndOfStatement();
5793 if (IDVal == ".cpsetup")
5794 return parseDirectiveCPSetup();
5796 if (IDVal == ".cpreturn")
5797 return parseDirectiveCPReturn();
5799 if (IDVal == ".module")
5800 return parseDirectiveModule();
5802 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5803 return parseInternalDirectiveReallowModule();
5805 if (IDVal == ".insn")
5806 return parseInsnDirective();
5811 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5812 // If this is not the end of the statement, report an error.
5813 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5814 reportParseError("unexpected token, expected end of statement");
5818 getTargetStreamer().reallowModuleDirective();
5820 getParser().Lex(); // Eat EndOfStatement token.
5824 extern "C" void LLVMInitializeMipsAsmParser() {
5825 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5826 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5827 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5828 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5831 #define GET_REGISTER_MATCHER
5832 #define GET_MATCHER_IMPLEMENTATION
5833 #include "MipsGenAsmMatcher.inc"