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());
1375 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1376 SmallVectorImpl<MCInst> &Instructions) {
1377 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1378 bool ExpandedJalSym = false;
1382 if (MCID.isBranch() || MCID.isCall()) {
1383 const unsigned Opcode = Inst.getOpcode();
1393 assert(hasCnMips() && "instruction only valid for octeon cpus");
1400 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1401 Offset = Inst.getOperand(2);
1402 if (!Offset.isImm())
1403 break; // We'll deal with this situation later on when applying fixups.
1404 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1405 return Error(IDLoc, "branch target out of range");
1406 if (OffsetToAlignment(Offset.getImm(),
1407 1LL << (inMicroMipsMode() ? 1 : 2)))
1408 return Error(IDLoc, "branch to misaligned address");
1422 case Mips::BGEZAL_MM:
1423 case Mips::BLTZAL_MM:
1426 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1427 Offset = Inst.getOperand(1);
1428 if (!Offset.isImm())
1429 break; // We'll deal with this situation later on when applying fixups.
1430 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1431 return Error(IDLoc, "branch target out of range");
1432 if (OffsetToAlignment(Offset.getImm(),
1433 1LL << (inMicroMipsMode() ? 1 : 2)))
1434 return Error(IDLoc, "branch to misaligned address");
1436 case Mips::BEQZ16_MM:
1437 case Mips::BEQZC16_MMR6:
1438 case Mips::BNEZ16_MM:
1439 case Mips::BNEZC16_MMR6:
1440 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1441 Offset = Inst.getOperand(1);
1442 if (!Offset.isImm())
1443 break; // We'll deal with this situation later on when applying fixups.
1444 if (!isIntN(8, Offset.getImm()))
1445 return Error(IDLoc, "branch target out of range");
1446 if (OffsetToAlignment(Offset.getImm(), 2LL))
1447 return Error(IDLoc, "branch to misaligned address");
1452 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1453 // We still accept it but it is a normal nop.
1454 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1455 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1456 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1461 const unsigned Opcode = Inst.getOpcode();
1473 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1474 // The offset is handled above
1475 Opnd = Inst.getOperand(1);
1477 return Error(IDLoc, "expected immediate operand kind");
1478 Imm = Opnd.getImm();
1479 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1480 Opcode == Mips::BBIT1 ? 63 : 31))
1481 return Error(IDLoc, "immediate operand value out of range");
1483 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1485 Inst.getOperand(1).setImm(Imm - 32);
1493 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1495 Opnd = Inst.getOperand(3);
1497 return Error(IDLoc, "expected immediate operand kind");
1498 Imm = Opnd.getImm();
1499 if (Imm < 0 || Imm > 31)
1500 return Error(IDLoc, "immediate operand value out of range");
1502 Opnd = Inst.getOperand(2);
1504 return Error(IDLoc, "expected immediate operand kind");
1505 Imm = Opnd.getImm();
1506 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1507 Opcode == Mips::EXTS ? 63 : 31))
1508 return Error(IDLoc, "immediate operand value out of range");
1510 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1511 Inst.getOperand(2).setImm(Imm - 32);
1517 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1518 Opnd = Inst.getOperand(2);
1520 return Error(IDLoc, "expected immediate operand kind");
1521 Imm = Opnd.getImm();
1522 if (!isInt<10>(Imm))
1523 return Error(IDLoc, "immediate operand value out of range");
1528 // This expansion is not in a function called by expandInstruction() because
1529 // the pseudo-instruction doesn't have a distinct opcode.
1530 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1532 warnIfNoMacro(IDLoc);
1534 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1536 // We can do this expansion if there's only 1 symbol in the argument
1538 if (countMCSymbolRefExpr(JalExpr) > 1)
1539 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1541 // FIXME: This is checking the expression can be handled by the later stages
1542 // of the assembler. We ought to leave it to those later stages but
1543 // we can't do that until we stop evaluateRelocExpr() rewriting the
1544 // expressions into non-equivalent forms.
1545 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1547 // FIXME: Add support for label+offset operands (currently causes an error).
1548 // FIXME: Add support for forward-declared local symbols.
1549 // FIXME: Add expansion for when the LargeGOT option is enabled.
1550 if (JalSym->isInSection() || JalSym->isTemporary()) {
1552 // If it's a local symbol and the O32 ABI is being used, we expand to:
1554 // R_(MICRO)MIPS_GOT16 label
1555 // addiu $25, $25, 0
1556 // R_(MICRO)MIPS_LO16 label
1558 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1559 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1562 LwInst.setOpcode(Mips::LW);
1563 LwInst.addOperand(MCOperand::createReg(Mips::T9));
1564 LwInst.addOperand(MCOperand::createReg(Mips::GP));
1565 LwInst.addOperand(MCOperand::createExpr(Got16RelocExpr));
1566 Instructions.push_back(LwInst);
1569 AddiuInst.setOpcode(Mips::ADDiu);
1570 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1571 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1572 AddiuInst.addOperand(MCOperand::createExpr(Lo16RelocExpr));
1573 Instructions.push_back(AddiuInst);
1574 } else if (isABI_N32() || isABI_N64()) {
1575 // If it's a local symbol and the N32/N64 ABIs are being used,
1577 // lw/ld $25, 0($gp)
1578 // R_(MICRO)MIPS_GOT_DISP label
1580 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1583 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1584 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1585 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1586 LoadInst.addOperand(MCOperand::createExpr(GotDispRelocExpr));
1587 Instructions.push_back(LoadInst);
1590 // If it's an external/weak symbol, we expand to:
1591 // lw/ld $25, 0($gp)
1592 // R_(MICRO)MIPS_CALL16 label
1594 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1597 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1598 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1599 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1600 LoadInst.addOperand(MCOperand::createExpr(Call16RelocExpr));
1601 Instructions.push_back(LoadInst);
1605 if (IsCpRestoreSet && inMicroMipsMode())
1606 JalrInst.setOpcode(Mips::JALRS_MM);
1608 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1609 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1610 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1612 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1613 // This relocation is supposed to be an optimization hint for the linker
1614 // and is not necessary for correctness.
1617 ExpandedJalSym = true;
1620 if (MCID.mayLoad() || MCID.mayStore()) {
1621 // Check the offset of memory operand, if it is a symbol
1622 // reference or immediate we may have to expand instructions.
1623 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1624 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1625 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1626 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1627 MCOperand &Op = Inst.getOperand(i);
1629 int MemOffset = Op.getImm();
1630 if (MemOffset < -32768 || MemOffset > 32767) {
1631 // Offset can't exceed 16bit value.
1632 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1635 } else if (Op.isExpr()) {
1636 const MCExpr *Expr = Op.getExpr();
1637 if (Expr->getKind() == MCExpr::SymbolRef) {
1638 const MCSymbolRefExpr *SR =
1639 static_cast<const MCSymbolRefExpr *>(Expr);
1640 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1642 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1645 } else if (!isEvaluated(Expr)) {
1646 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1654 if (inMicroMipsMode()) {
1655 if (MCID.mayLoad()) {
1656 // Try to create 16-bit GP relative load instruction.
1657 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1658 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1659 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1660 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1661 MCOperand &Op = Inst.getOperand(i);
1663 int MemOffset = Op.getImm();
1664 MCOperand &DstReg = Inst.getOperand(0);
1665 MCOperand &BaseReg = Inst.getOperand(1);
1666 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1667 getContext().getRegisterInfo()->getRegClass(
1668 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1669 (BaseReg.getReg() == Mips::GP ||
1670 BaseReg.getReg() == Mips::GP_64)) {
1672 TmpInst.setLoc(IDLoc);
1673 TmpInst.setOpcode(Mips::LWGP_MM);
1674 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1675 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1676 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1677 Instructions.push_back(TmpInst);
1685 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1690 switch (Inst.getOpcode()) {
1693 case Mips::ADDIUS5_MM:
1694 Opnd = Inst.getOperand(2);
1696 return Error(IDLoc, "expected immediate operand kind");
1697 Imm = Opnd.getImm();
1698 if (Imm < -8 || Imm > 7)
1699 return Error(IDLoc, "immediate operand value out of range");
1701 case Mips::ADDIUSP_MM:
1702 Opnd = Inst.getOperand(0);
1704 return Error(IDLoc, "expected immediate operand kind");
1705 Imm = Opnd.getImm();
1706 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1708 return Error(IDLoc, "immediate operand value out of range");
1710 case Mips::SLL16_MM:
1711 case Mips::SRL16_MM:
1712 Opnd = Inst.getOperand(2);
1714 return Error(IDLoc, "expected immediate operand kind");
1715 Imm = Opnd.getImm();
1716 if (Imm < 1 || Imm > 8)
1717 return Error(IDLoc, "immediate operand value out of range");
1720 Opnd = Inst.getOperand(1);
1722 return Error(IDLoc, "expected immediate operand kind");
1723 Imm = Opnd.getImm();
1724 if (Imm < -1 || Imm > 126)
1725 return Error(IDLoc, "immediate operand value out of range");
1727 case Mips::ADDIUR2_MM:
1728 Opnd = Inst.getOperand(2);
1730 return Error(IDLoc, "expected immediate operand kind");
1731 Imm = Opnd.getImm();
1732 if (!(Imm == 1 || Imm == -1 ||
1733 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1734 return Error(IDLoc, "immediate operand value out of range");
1736 case Mips::ADDIUR1SP_MM:
1737 Opnd = Inst.getOperand(1);
1739 return Error(IDLoc, "expected immediate operand kind");
1740 Imm = Opnd.getImm();
1741 if (OffsetToAlignment(Imm, 4LL))
1742 return Error(IDLoc, "misaligned immediate operand value");
1743 if (Imm < 0 || Imm > 255)
1744 return Error(IDLoc, "immediate operand value out of range");
1746 case Mips::ANDI16_MM:
1747 Opnd = Inst.getOperand(2);
1749 return Error(IDLoc, "expected immediate operand kind");
1750 Imm = Opnd.getImm();
1751 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1752 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1753 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1754 return Error(IDLoc, "immediate operand value out of range");
1756 case Mips::LBU16_MM:
1757 Opnd = Inst.getOperand(2);
1759 return Error(IDLoc, "expected immediate operand kind");
1760 Imm = Opnd.getImm();
1761 if (Imm < -1 || Imm > 14)
1762 return Error(IDLoc, "immediate operand value out of range");
1771 Opnd = Inst.getOperand(2);
1773 return Error(IDLoc, "expected immediate operand kind");
1774 Imm = Opnd.getImm();
1775 if (Imm < 0 || Imm > 15)
1776 return Error(IDLoc, "immediate operand value out of range");
1778 case Mips::LHU16_MM:
1780 Opnd = Inst.getOperand(2);
1782 return Error(IDLoc, "expected immediate operand kind");
1783 Imm = Opnd.getImm();
1784 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1785 return Error(IDLoc, "immediate operand value out of range");
1789 Opnd = Inst.getOperand(2);
1791 return Error(IDLoc, "expected immediate operand kind");
1792 Imm = Opnd.getImm();
1793 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1794 return Error(IDLoc, "immediate operand value out of range");
1796 case Mips::PREFX_MM:
1799 Opnd = Inst.getOperand(2);
1801 return Error(IDLoc, "expected immediate operand kind");
1802 Imm = Opnd.getImm();
1803 if (!isUInt<5>(Imm))
1804 return Error(IDLoc, "immediate operand value out of range");
1806 case Mips::ADDIUPC_MM:
1807 MCOperand Opnd = Inst.getOperand(1);
1809 return Error(IDLoc, "expected immediate operand kind");
1810 int Imm = Opnd.getImm();
1811 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1812 return Error(IDLoc, "immediate operand value out of range");
1817 if (needsExpansion(Inst)) {
1818 if (expandInstruction(Inst, IDLoc, Instructions))
1821 Instructions.push_back(Inst);
1823 // If this instruction has a delay slot and .set reorder is active,
1824 // emit a NOP after it.
1825 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1826 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1828 if ((Inst.getOpcode() == Mips::JalOneReg ||
1829 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1830 isPicAndNotNxxAbi()) {
1831 if (IsCpRestoreSet) {
1832 // We need a NOP between the JALR and the LW:
1833 // If .set reorder has been used, we've already emitted a NOP.
1834 // If .set noreorder has been used, we need to emit a NOP at this point.
1835 if (!AssemblerOptions.back()->isReorder())
1836 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1838 // Load the $gp from the stack.
1839 SmallVector<MCInst, 3> LoadInsts;
1840 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1843 for (const MCInst &Inst : LoadInsts)
1844 Instructions.push_back(Inst);
1847 Warning(IDLoc, "no .cprestore used in PIC mode");
1853 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1855 switch (Inst.getOpcode()) {
1856 case Mips::LoadImm32:
1857 case Mips::LoadImm64:
1858 case Mips::LoadAddrImm32:
1859 case Mips::LoadAddrImm64:
1860 case Mips::LoadAddrReg32:
1861 case Mips::LoadAddrReg64:
1862 case Mips::B_MM_Pseudo:
1863 case Mips::B_MMR6_Pseudo:
1866 case Mips::JalOneReg:
1867 case Mips::JalTwoReg:
1886 case Mips::SDivMacro:
1887 case Mips::UDivMacro:
1888 case Mips::DSDivMacro:
1889 case Mips::DUDivMacro:
1898 if ((Inst.getNumOperands() == 3) &&
1899 Inst.getOperand(0).isReg() &&
1900 Inst.getOperand(1).isReg() &&
1901 Inst.getOperand(2).isImm()) {
1902 int64_t ImmValue = Inst.getOperand(2).getImm();
1903 return !isInt<16>(ImmValue);
1909 if ((Inst.getNumOperands() == 3) &&
1910 Inst.getOperand(0).isReg() &&
1911 Inst.getOperand(1).isReg() &&
1912 Inst.getOperand(2).isImm()) {
1913 int64_t ImmValue = Inst.getOperand(2).getImm();
1914 return !isUInt<16>(ImmValue);
1922 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1923 SmallVectorImpl<MCInst> &Instructions) {
1924 switch (Inst.getOpcode()) {
1925 default: llvm_unreachable("unimplemented expansion");
1926 case Mips::LoadImm32:
1927 return expandLoadImm(Inst, true, IDLoc, Instructions);
1928 case Mips::LoadImm64:
1929 return expandLoadImm(Inst, false, IDLoc, Instructions);
1930 case Mips::LoadAddrImm32:
1931 case Mips::LoadAddrImm64:
1932 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1933 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1934 "expected immediate operand kind");
1936 return expandLoadAddress(
1937 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1938 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1939 case Mips::LoadAddrReg32:
1940 case Mips::LoadAddrReg64:
1941 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1942 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1943 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1944 "expected immediate operand kind");
1946 return expandLoadAddress(
1947 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1948 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1949 case Mips::B_MM_Pseudo:
1950 case Mips::B_MMR6_Pseudo:
1951 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1954 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1955 case Mips::JalOneReg:
1956 case Mips::JalTwoReg:
1957 return expandJalWithRegs(Inst, IDLoc, Instructions);
1960 return expandBranchImm(Inst, IDLoc, Instructions);
1977 return expandCondBranches(Inst, IDLoc, Instructions);
1978 case Mips::SDivMacro:
1979 return expandDiv(Inst, IDLoc, Instructions, false, true);
1980 case Mips::DSDivMacro:
1981 return expandDiv(Inst, IDLoc, Instructions, true, true);
1982 case Mips::UDivMacro:
1983 return expandDiv(Inst, IDLoc, Instructions, false, false);
1984 case Mips::DUDivMacro:
1985 return expandDiv(Inst, IDLoc, Instructions, true, false);
1987 return expandUlhu(Inst, IDLoc, Instructions);
1989 return expandUlw(Inst, IDLoc, Instructions);
1998 return expandAliasImmediate(Inst, IDLoc, Instructions);
2003 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
2004 SmallVectorImpl<MCInst> &Instructions) {
2006 tmpInst.setOpcode(Opcode);
2007 tmpInst.addOperand(MCOperand::createReg(Reg0));
2008 tmpInst.addOperand(Op1);
2009 tmpInst.setLoc(IDLoc);
2010 Instructions.push_back(tmpInst);
2013 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
2014 SmallVectorImpl<MCInst> &Instructions) {
2015 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
2018 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
2019 SmallVectorImpl<MCInst> &Instructions) {
2020 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
2023 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
2024 SmallVectorImpl<MCInst> &Instructions) {
2026 tmpInst.setOpcode(Opcode);
2027 tmpInst.addOperand(MCOperand::createImm(Imm1));
2028 tmpInst.addOperand(MCOperand::createImm(Imm2));
2029 tmpInst.setLoc(IDLoc);
2030 Instructions.push_back(tmpInst);
2033 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
2034 SmallVectorImpl<MCInst> &Instructions) {
2036 tmpInst.setOpcode(Opcode);
2037 tmpInst.addOperand(MCOperand::createReg(Reg0));
2038 tmpInst.setLoc(IDLoc);
2039 Instructions.push_back(tmpInst);
2042 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
2043 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2045 tmpInst.setOpcode(Opcode);
2046 tmpInst.addOperand(MCOperand::createReg(Reg0));
2047 tmpInst.addOperand(MCOperand::createReg(Reg1));
2048 tmpInst.addOperand(Op2);
2049 tmpInst.setLoc(IDLoc);
2050 Instructions.push_back(tmpInst);
2053 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
2054 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2055 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
2059 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
2060 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2061 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
2065 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
2066 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2067 if (ShiftAmount >= 32) {
2068 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
2073 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
2075 } // end anonymous namespace.
2077 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2078 SmallVectorImpl<MCInst> &Instructions) {
2079 // Create a JALR instruction which is going to replace the pseudo-JAL.
2081 JalrInst.setLoc(IDLoc);
2082 const MCOperand FirstRegOp = Inst.getOperand(0);
2083 const unsigned Opcode = Inst.getOpcode();
2085 if (Opcode == Mips::JalOneReg) {
2086 // jal $rs => jalr $rs
2087 if (IsCpRestoreSet && inMicroMipsMode()) {
2088 JalrInst.setOpcode(Mips::JALRS16_MM);
2089 JalrInst.addOperand(FirstRegOp);
2090 } else if (inMicroMipsMode()) {
2091 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2092 JalrInst.addOperand(FirstRegOp);
2094 JalrInst.setOpcode(Mips::JALR);
2095 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2096 JalrInst.addOperand(FirstRegOp);
2098 } else if (Opcode == Mips::JalTwoReg) {
2099 // jal $rd, $rs => jalr $rd, $rs
2100 if (IsCpRestoreSet && inMicroMipsMode())
2101 JalrInst.setOpcode(Mips::JALRS_MM);
2103 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2104 JalrInst.addOperand(FirstRegOp);
2105 const MCOperand SecondRegOp = Inst.getOperand(1);
2106 JalrInst.addOperand(SecondRegOp);
2108 Instructions.push_back(JalrInst);
2110 // If .set reorder is active and branch instruction has a delay slot,
2111 // emit a NOP after it.
2112 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2113 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2114 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2120 /// Can the value be represented by a unsigned N-bit value and a shift left?
2121 template<unsigned N>
2122 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2123 unsigned BitNum = findFirstSet(x);
2125 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2128 /// Load (or add) an immediate into a register.
2130 /// @param ImmValue The immediate to load.
2131 /// @param DstReg The register that will hold the immediate.
2132 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2133 /// for a simple initialization.
2134 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2135 /// @param IsAddress True if the immediate represents an address. False if it
2137 /// @param IDLoc Location of the immediate in the source file.
2138 /// @param Instructions The instructions emitted by this expansion.
2139 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2140 unsigned SrcReg, bool Is32BitImm,
2141 bool IsAddress, SMLoc IDLoc,
2142 SmallVectorImpl<MCInst> &Instructions) {
2143 if (!Is32BitImm && !isGP64bit()) {
2144 Error(IDLoc, "instruction requires a 64-bit architecture");
2149 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2150 // Sign extend up to 64-bit so that the predicates match the hardware
2151 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2153 ImmValue = SignExtend64<32>(ImmValue);
2155 Error(IDLoc, "instruction requires a 32-bit immediate");
2160 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2161 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2163 bool UseSrcReg = false;
2164 if (SrcReg != Mips::NoRegister)
2167 unsigned TmpReg = DstReg;
2168 if (UseSrcReg && (DstReg == SrcReg)) {
2169 // At this point we need AT to perform the expansions and we exit if it is
2171 unsigned ATReg = getATReg(IDLoc);
2177 if (isInt<16>(ImmValue)) {
2181 // This doesn't quite follow the usual ABI expectations for N32 but matches
2182 // traditional assembler behaviour. N32 would normally use addiu for both
2183 // integers and addresses.
2184 if (IsAddress && !Is32BitImm) {
2185 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2189 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2193 if (isUInt<16>(ImmValue)) {
2194 unsigned TmpReg = DstReg;
2195 if (SrcReg == DstReg) {
2196 TmpReg = getATReg(IDLoc);
2201 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2203 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2207 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2208 warnIfNoMacro(IDLoc);
2210 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2211 uint16_t Bits15To0 = ImmValue & 0xffff;
2213 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2214 // Traditional behaviour seems to special case this particular value. It's
2215 // not clear why other masks are handled differently.
2216 if (ImmValue == 0xffffffff) {
2217 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2218 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2220 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2224 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2226 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2227 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2229 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2231 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2235 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2237 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2239 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2243 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2245 Error(IDLoc, "instruction requires a 32-bit immediate");
2249 // Traditionally, these immediates are shifted as little as possible and as
2250 // such we align the most significant bit to bit 15 of our temporary.
2251 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2252 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2253 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2254 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2255 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2256 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2259 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2264 warnIfNoMacro(IDLoc);
2266 // The remaining case is packed with a sequence of dsll and ori with zeros
2267 // being omitted and any neighbouring dsll's being coalesced.
2268 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2270 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2271 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2272 IDLoc, Instructions))
2275 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2276 // skip it and defer the shift to the next chunk.
2277 unsigned ShiftCarriedForwards = 16;
2278 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2279 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2281 if (ImmChunk != 0) {
2282 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2284 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2285 ShiftCarriedForwards = 0;
2288 ShiftCarriedForwards += 16;
2290 ShiftCarriedForwards -= 16;
2292 // Finish any remaining shifts left by trailing zeros.
2293 if (ShiftCarriedForwards)
2294 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2298 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2303 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2304 SmallVectorImpl<MCInst> &Instructions) {
2305 const MCOperand &ImmOp = Inst.getOperand(1);
2306 assert(ImmOp.isImm() && "expected immediate operand kind");
2307 const MCOperand &DstRegOp = Inst.getOperand(0);
2308 assert(DstRegOp.isReg() && "expected register operand kind");
2310 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2311 Is32BitImm, false, IDLoc, Instructions))
2317 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2318 const MCOperand &Offset,
2319 bool Is32BitAddress, SMLoc IDLoc,
2320 SmallVectorImpl<MCInst> &Instructions) {
2321 // la can't produce a usable address when addresses are 64-bit.
2322 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2323 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2324 // We currently can't do this because we depend on the equality
2325 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2326 Error(IDLoc, "la used to load 64-bit address");
2327 // Continue as if we had 'dla' instead.
2328 Is32BitAddress = false;
2331 // dla requires 64-bit addresses.
2332 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2333 Error(IDLoc, "instruction requires a 64-bit architecture");
2337 if (!Offset.isImm())
2338 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2339 Is32BitAddress, IDLoc, Instructions);
2341 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2342 IDLoc, Instructions);
2345 bool MipsAsmParser::loadAndAddSymbolAddress(
2346 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2347 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2348 warnIfNoMacro(IDLoc);
2350 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2351 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2352 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2353 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2354 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2356 bool UseSrcReg = SrcReg != Mips::NoRegister;
2358 // This is the 64-bit symbol address expansion.
2359 if (ABI.ArePtrs64bit() && isGP64bit()) {
2360 // We always need AT for the 64-bit expansion.
2361 // If it is not available we exit.
2362 unsigned ATReg = getATReg(IDLoc);
2366 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2367 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2368 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2369 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2371 if (UseSrcReg && (DstReg == SrcReg)) {
2372 // If $rs is the same as $rd:
2373 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2374 // daddiu $at, $at, %higher(sym)
2375 // dsll $at, $at, 16
2376 // daddiu $at, $at, %hi(sym)
2377 // dsll $at, $at, 16
2378 // daddiu $at, $at, %lo(sym)
2379 // daddu $rd, $at, $rd
2380 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2382 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2383 IDLoc, Instructions);
2384 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2385 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2387 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2388 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2390 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2395 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2396 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2397 // lui $at, %hi(sym)
2398 // daddiu $rd, $rd, %higher(sym)
2399 // daddiu $at, $at, %lo(sym)
2400 // dsll32 $rd, $rd, 0
2401 // daddu $rd, $rd, $at
2402 // (daddu $rd, $rd, $rs)
2403 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2405 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2407 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2408 IDLoc, Instructions);
2409 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2411 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2412 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2414 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2419 // And now, the 32-bit symbol address expansion:
2420 // If $rs is the same as $rd:
2421 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2422 // ori $at, $at, %lo(sym)
2423 // addu $rd, $at, $rd
2424 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2425 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2426 // ori $rd, $rd, %lo(sym)
2427 // (addu $rd, $rd, $rs)
2428 unsigned TmpReg = DstReg;
2429 if (UseSrcReg && (DstReg == SrcReg)) {
2430 // If $rs is the same as $rd, we need to use AT.
2431 // If it is not available we exit.
2432 unsigned ATReg = getATReg(IDLoc);
2438 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2439 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2443 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2445 assert(DstReg == TmpReg);
2450 bool MipsAsmParser::expandUncondBranchMMPseudo(
2451 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2452 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2453 "unexpected number of operands");
2455 MCOperand Offset = Inst.getOperand(0);
2456 if (Offset.isExpr()) {
2458 Inst.setOpcode(Mips::BEQ_MM);
2459 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2460 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2461 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2463 assert(Offset.isImm() && "expected immediate operand kind");
2464 if (isIntN(11, Offset.getImm())) {
2465 // If offset fits into 11 bits then this instruction becomes microMIPS
2466 // 16-bit unconditional branch instruction.
2467 if (inMicroMipsMode())
2468 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2470 if (!isIntN(17, Offset.getImm()))
2471 Error(IDLoc, "branch target out of range");
2472 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2473 Error(IDLoc, "branch to misaligned address");
2475 Inst.setOpcode(Mips::BEQ_MM);
2476 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2477 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2478 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2481 Instructions.push_back(Inst);
2483 // If .set reorder is active and branch instruction has a delay slot,
2484 // emit a NOP after it.
2485 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2486 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2487 createNop(true, IDLoc, Instructions);
2492 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2493 SmallVectorImpl<MCInst> &Instructions) {
2494 const MCOperand &DstRegOp = Inst.getOperand(0);
2495 assert(DstRegOp.isReg() && "expected register operand kind");
2497 const MCOperand &ImmOp = Inst.getOperand(1);
2498 assert(ImmOp.isImm() && "expected immediate operand kind");
2500 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2501 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2503 unsigned OpCode = 0;
2504 switch(Inst.getOpcode()) {
2512 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2516 int64_t ImmValue = ImmOp.getImm();
2517 if (ImmValue == 0) {
2519 BranchInst.setOpcode(OpCode);
2520 BranchInst.addOperand(DstRegOp);
2521 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2522 BranchInst.addOperand(MemOffsetOp);
2523 Instructions.push_back(BranchInst);
2525 warnIfNoMacro(IDLoc);
2527 unsigned ATReg = getATReg(IDLoc);
2531 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2532 IDLoc, Instructions))
2536 BranchInst.setOpcode(OpCode);
2537 BranchInst.addOperand(DstRegOp);
2538 BranchInst.addOperand(MCOperand::createReg(ATReg));
2539 BranchInst.addOperand(MemOffsetOp);
2540 Instructions.push_back(BranchInst);
2545 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2546 SmallVectorImpl<MCInst> &Instructions,
2547 bool isLoad, bool isImmOpnd) {
2549 unsigned ImmOffset, HiOffset, LoOffset;
2550 const MCExpr *ExprOffset;
2552 // 1st operand is either the source or destination register.
2553 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2554 unsigned RegOpNum = Inst.getOperand(0).getReg();
2555 // 2nd operand is the base register.
2556 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2557 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2558 // 3rd operand is either an immediate or expression.
2560 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2561 ImmOffset = Inst.getOperand(2).getImm();
2562 LoOffset = ImmOffset & 0x0000ffff;
2563 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2564 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2565 if (LoOffset & 0x8000)
2568 ExprOffset = Inst.getOperand(2).getExpr();
2569 // All instructions will have the same location.
2570 TempInst.setLoc(IDLoc);
2571 // These are some of the types of expansions we perform here:
2572 // 1) lw $8, sym => lui $8, %hi(sym)
2573 // lw $8, %lo(sym)($8)
2574 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2576 // lw $8, %lo(offset)($9)
2577 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2579 // lw $8, %lo(offset)($at)
2580 // 4) sw $8, sym => lui $at, %hi(sym)
2581 // sw $8, %lo(sym)($at)
2582 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2584 // sw $8, %lo(offset)($at)
2585 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2586 // ldc1 $f0, %lo(sym)($at)
2588 // For load instructions we can use the destination register as a temporary
2589 // if base and dst are different (examples 1 and 2) and if the base register
2590 // is general purpose otherwise we must use $at (example 6) and error if it's
2591 // not available. For stores we must use $at (examples 4 and 5) because we
2592 // must not clobber the source register setting up the offset.
2593 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2594 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2595 unsigned RegClassIDOp0 =
2596 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2597 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2598 (RegClassIDOp0 == Mips::GPR64RegClassID);
2599 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2600 TmpRegNum = RegOpNum;
2602 // At this point we need AT to perform the expansions and we exit if it is
2604 TmpRegNum = getATReg(IDLoc);
2609 TempInst.setOpcode(Mips::LUi);
2610 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2612 TempInst.addOperand(MCOperand::createImm(HiOffset));
2614 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2615 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2617 // Add the instruction to the list.
2618 Instructions.push_back(TempInst);
2619 // Prepare TempInst for next instruction.
2621 // Add temp register to base.
2622 if (BaseRegNum != Mips::ZERO) {
2623 TempInst.setOpcode(Mips::ADDu);
2624 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2625 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2626 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2627 Instructions.push_back(TempInst);
2630 // And finally, create original instruction with low part
2631 // of offset and new base.
2632 TempInst.setOpcode(Inst.getOpcode());
2633 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2634 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2636 TempInst.addOperand(MCOperand::createImm(LoOffset));
2638 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2639 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2641 Instructions.push_back(TempInst);
2646 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2647 SmallVectorImpl<MCInst> &Instructions) {
2648 unsigned OpNum = Inst.getNumOperands();
2649 unsigned Opcode = Inst.getOpcode();
2650 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2652 assert (Inst.getOperand(OpNum - 1).isImm() &&
2653 Inst.getOperand(OpNum - 2).isReg() &&
2654 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2656 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2657 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2658 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2659 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2660 // It can be implemented as SWM16 or LWM16 instruction.
2661 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2663 Inst.setOpcode(NewOpcode);
2664 Instructions.push_back(Inst);
2668 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2669 SmallVectorImpl<MCInst> &Instructions) {
2670 unsigned PseudoOpcode = Inst.getOpcode();
2671 unsigned SrcReg = Inst.getOperand(0).getReg();
2672 unsigned TrgReg = Inst.getOperand(1).getReg();
2673 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2675 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2676 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2678 switch (PseudoOpcode) {
2683 AcceptsEquality = false;
2684 ReverseOrderSLT = false;
2685 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2686 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2687 ZeroSrcOpcode = Mips::BGTZ;
2688 ZeroTrgOpcode = Mips::BLTZ;
2694 AcceptsEquality = true;
2695 ReverseOrderSLT = true;
2696 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2697 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2698 ZeroSrcOpcode = Mips::BGEZ;
2699 ZeroTrgOpcode = Mips::BLEZ;
2705 AcceptsEquality = true;
2706 ReverseOrderSLT = false;
2707 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2708 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2709 ZeroSrcOpcode = Mips::BLEZ;
2710 ZeroTrgOpcode = Mips::BGEZ;
2716 AcceptsEquality = false;
2717 ReverseOrderSLT = true;
2718 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2719 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2720 ZeroSrcOpcode = Mips::BLTZ;
2721 ZeroTrgOpcode = Mips::BGTZ;
2724 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2728 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2729 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2730 if (IsSrcRegZero && IsTrgRegZero) {
2731 // FIXME: All of these Opcode-specific if's are needed for compatibility
2732 // with GAS' behaviour. However, they may not generate the most efficient
2733 // code in some circumstances.
2734 if (PseudoOpcode == Mips::BLT) {
2735 BranchInst.setOpcode(Mips::BLTZ);
2736 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2737 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2738 Instructions.push_back(BranchInst);
2741 if (PseudoOpcode == Mips::BLE) {
2742 BranchInst.setOpcode(Mips::BLEZ);
2743 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2744 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2745 Instructions.push_back(BranchInst);
2746 Warning(IDLoc, "branch is always taken");
2749 if (PseudoOpcode == Mips::BGE) {
2750 BranchInst.setOpcode(Mips::BGEZ);
2751 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2752 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2753 Instructions.push_back(BranchInst);
2754 Warning(IDLoc, "branch is always taken");
2757 if (PseudoOpcode == Mips::BGT) {
2758 BranchInst.setOpcode(Mips::BGTZ);
2759 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2760 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2761 Instructions.push_back(BranchInst);
2764 if (PseudoOpcode == Mips::BGTU) {
2765 BranchInst.setOpcode(Mips::BNE);
2766 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2767 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2768 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2769 Instructions.push_back(BranchInst);
2772 if (AcceptsEquality) {
2773 // If both registers are $0 and the pseudo-branch accepts equality, it
2774 // will always be taken, so we emit an unconditional branch.
2775 BranchInst.setOpcode(Mips::BEQ);
2776 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2777 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2778 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2779 Instructions.push_back(BranchInst);
2780 Warning(IDLoc, "branch is always taken");
2783 // If both registers are $0 and the pseudo-branch does not accept
2784 // equality, it will never be taken, so we don't have to emit anything.
2787 if (IsSrcRegZero || IsTrgRegZero) {
2788 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2789 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2790 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2791 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2792 // the pseudo-branch will never be taken, so we don't emit anything.
2793 // This only applies to unsigned pseudo-branches.
2796 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2797 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2798 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2799 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2800 // the pseudo-branch will always be taken, so we emit an unconditional
2802 // This only applies to unsigned pseudo-branches.
2803 BranchInst.setOpcode(Mips::BEQ);
2804 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2805 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2806 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2807 Instructions.push_back(BranchInst);
2808 Warning(IDLoc, "branch is always taken");
2812 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2813 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2814 // the pseudo-branch will be taken only when the non-zero register is
2815 // different from 0, so we emit a BNEZ.
2817 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2818 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2819 // the pseudo-branch will be taken only when the non-zero register is
2820 // equal to 0, so we emit a BEQZ.
2822 // Because only BLEU and BGEU branch on equality, we can use the
2823 // AcceptsEquality variable to decide when to emit the BEQZ.
2824 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2825 BranchInst.addOperand(
2826 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2827 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2828 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2829 Instructions.push_back(BranchInst);
2832 // If we have a signed pseudo-branch and one of the registers is $0,
2833 // we can use an appropriate compare-to-zero branch. We select which one
2834 // to use in the switch statement above.
2835 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2836 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2837 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2838 Instructions.push_back(BranchInst);
2842 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2843 // expansions. If it is not available, we return.
2844 unsigned ATRegNum = getATReg(IDLoc);
2848 warnIfNoMacro(IDLoc);
2850 // SLT fits well with 2 of our 4 pseudo-branches:
2851 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2852 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2853 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2854 // This is accomplished by using a BNEZ with the result of the SLT.
2856 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2857 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2858 // Because only BGE and BLE branch on equality, we can use the
2859 // AcceptsEquality variable to decide when to emit the BEQZ.
2860 // Note that the order of the SLT arguments doesn't change between
2863 // The same applies to the unsigned variants, except that SLTu is used
2866 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2867 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2868 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2869 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2870 Instructions.push_back(SetInst);
2873 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2875 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQL : Mips::BNEL);
2876 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2877 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2878 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2879 Instructions.push_back(BranchInst);
2883 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2884 SmallVectorImpl<MCInst> &Instructions,
2885 const bool IsMips64, const bool Signed) {
2886 if (hasMips32r6()) {
2887 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2891 warnIfNoMacro(IDLoc);
2893 const MCOperand &RsRegOp = Inst.getOperand(0);
2894 assert(RsRegOp.isReg() && "expected register operand kind");
2895 unsigned RsReg = RsRegOp.getReg();
2897 const MCOperand &RtRegOp = Inst.getOperand(1);
2898 assert(RtRegOp.isReg() && "expected register operand kind");
2899 unsigned RtReg = RtRegOp.getReg();
2904 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2905 ZeroReg = Mips::ZERO_64;
2907 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2908 ZeroReg = Mips::ZERO;
2911 bool UseTraps = useTraps();
2913 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2914 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2915 Warning(IDLoc, "dividing zero by zero");
2917 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2919 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2923 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2927 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2932 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2933 Warning(IDLoc, "division by zero");
2936 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2940 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2945 // FIXME: The values for these two BranchTarget variables may be different in
2946 // micromips. These magic numbers need to be removed.
2947 unsigned BranchTargetNoTraps;
2948 unsigned BranchTarget;
2951 BranchTarget = IsMips64 ? 12 : 8;
2952 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2954 BranchTarget = IsMips64 ? 20 : 16;
2955 BranchTargetNoTraps = 8;
2956 // Branch to the li instruction.
2957 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2961 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2964 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2967 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2971 unsigned ATReg = getATReg(IDLoc);
2975 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2977 // Branch to the mflo instruction.
2978 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2979 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2980 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2982 // Branch to the mflo instruction.
2983 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2984 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2988 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2990 // Branch to the mflo instruction.
2991 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2992 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2993 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2995 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2999 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
3000 SmallVectorImpl<MCInst> &Instructions) {
3001 if (hasMips32r6() || hasMips64r6()) {
3002 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3006 warnIfNoMacro(IDLoc);
3008 const MCOperand &DstRegOp = Inst.getOperand(0);
3009 assert(DstRegOp.isReg() && "expected register operand kind");
3011 const MCOperand &SrcRegOp = Inst.getOperand(1);
3012 assert(SrcRegOp.isReg() && "expected register operand kind");
3014 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3015 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3017 unsigned DstReg = DstRegOp.getReg();
3018 unsigned SrcReg = SrcRegOp.getReg();
3019 int64_t OffsetValue = OffsetImmOp.getImm();
3021 // NOTE: We always need AT for ULHU, as it is always used as the source
3022 // register for one of the LBu's.
3023 unsigned ATReg = getATReg(IDLoc);
3027 // When the value of offset+1 does not fit in 16 bits, we have to load the
3028 // offset in AT, (D)ADDu the original source register (if there was one), and
3029 // then use AT as the source register for the 2 generated LBu's.
3030 bool LoadedOffsetInAT = false;
3031 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3032 LoadedOffsetInAT = true;
3034 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3035 true, IDLoc, Instructions))
3038 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3039 // because it will make our output more similar to GAS'. For example,
3040 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3041 // instead of just an "ori $1, $9, 32768".
3042 // NOTE: If there is no source register specified in the ULHU, the parser
3043 // will interpret it as $0.
3044 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3045 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3048 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3049 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3050 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3052 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3054 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3055 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3057 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3058 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3061 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3064 TmpInst.setOpcode(Mips::LBu);
3065 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
3066 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
3067 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
3068 Instructions.push_back(TmpInst);
3071 TmpInst.setOpcode(Mips::LBu);
3072 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
3073 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
3074 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
3075 Instructions.push_back(TmpInst);
3078 TmpInst.setOpcode(Mips::SLL);
3079 TmpInst.addOperand(MCOperand::createReg(SllReg));
3080 TmpInst.addOperand(MCOperand::createReg(SllReg));
3081 TmpInst.addOperand(MCOperand::createImm(8));
3082 Instructions.push_back(TmpInst);
3085 TmpInst.setOpcode(Mips::OR);
3086 TmpInst.addOperand(MCOperand::createReg(DstReg));
3087 TmpInst.addOperand(MCOperand::createReg(DstReg));
3088 TmpInst.addOperand(MCOperand::createReg(ATReg));
3089 Instructions.push_back(TmpInst);
3094 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3095 SmallVectorImpl<MCInst> &Instructions) {
3096 if (hasMips32r6() || hasMips64r6()) {
3097 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3101 const MCOperand &DstRegOp = Inst.getOperand(0);
3102 assert(DstRegOp.isReg() && "expected register operand kind");
3104 const MCOperand &SrcRegOp = Inst.getOperand(1);
3105 assert(SrcRegOp.isReg() && "expected register operand kind");
3107 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3108 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3110 unsigned SrcReg = SrcRegOp.getReg();
3111 int64_t OffsetValue = OffsetImmOp.getImm();
3114 // When the value of offset+3 does not fit in 16 bits, we have to load the
3115 // offset in AT, (D)ADDu the original source register (if there was one), and
3116 // then use AT as the source register for the generated LWL and LWR.
3117 bool LoadedOffsetInAT = false;
3118 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3119 ATReg = getATReg(IDLoc);
3122 LoadedOffsetInAT = true;
3124 warnIfNoMacro(IDLoc);
3126 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3127 true, IDLoc, Instructions))
3130 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3131 // because it will make our output more similar to GAS'. For example,
3132 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3133 // instead of just an "ori $1, $9, 32768".
3134 // NOTE: If there is no source register specified in the ULW, the parser
3135 // will interpret it as $0.
3136 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3137 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3140 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3141 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3143 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3144 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3146 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3147 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3150 MCInst LeftLoadInst;
3151 LeftLoadInst.setOpcode(Mips::LWL);
3152 LeftLoadInst.addOperand(DstRegOp);
3153 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3154 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3155 Instructions.push_back(LeftLoadInst);
3157 MCInst RightLoadInst;
3158 RightLoadInst.setOpcode(Mips::LWR);
3159 RightLoadInst.addOperand(DstRegOp);
3160 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3161 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3162 Instructions.push_back(RightLoadInst);
3167 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3168 SmallVectorImpl<MCInst> &Instructions) {
3170 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3171 assert (Inst.getOperand(0).isReg() &&
3172 Inst.getOperand(1).isReg() &&
3173 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3175 unsigned ATReg = Mips::NoRegister;
3176 unsigned FinalDstReg = Mips::NoRegister;
3177 unsigned DstReg = Inst.getOperand(0).getReg();
3178 unsigned SrcReg = Inst.getOperand(1).getReg();
3179 int64_t ImmValue = Inst.getOperand(2).getImm();
3181 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3183 unsigned FinalOpcode = Inst.getOpcode();
3185 if (DstReg == SrcReg) {
3186 ATReg = getATReg(Inst.getLoc());
3189 FinalDstReg = DstReg;
3193 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3194 switch (FinalOpcode) {
3196 llvm_unreachable("unimplemented expansion");
3198 FinalOpcode = Mips::ADD;
3201 FinalOpcode = Mips::ADDu;
3204 FinalOpcode = Mips::AND;
3206 case (Mips::NORImm):
3207 FinalOpcode = Mips::NOR;
3210 FinalOpcode = Mips::OR;
3213 FinalOpcode = Mips::SLT;
3216 FinalOpcode = Mips::SLTu;
3219 FinalOpcode = Mips::XOR;
3226 tmpInst.setLoc(Inst.getLoc());
3227 tmpInst.setOpcode(FinalOpcode);
3228 if (FinalDstReg == Mips::NoRegister) {
3229 tmpInst.addOperand(MCOperand::createReg(DstReg));
3230 tmpInst.addOperand(MCOperand::createReg(DstReg));
3231 tmpInst.addOperand(MCOperand::createReg(SrcReg));
3233 tmpInst.addOperand(MCOperand::createReg(FinalDstReg));
3234 tmpInst.addOperand(MCOperand::createReg(FinalDstReg));
3235 tmpInst.addOperand(MCOperand::createReg(DstReg));
3237 Instructions.push_back(tmpInst);
3243 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3244 SmallVectorImpl<MCInst> &Instructions) {
3246 if (hasShortDelaySlot) {
3247 NopInst.setOpcode(Mips::MOVE16_MM);
3248 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3249 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3251 NopInst.setOpcode(Mips::SLL);
3252 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3253 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3254 NopInst.addOperand(MCOperand::createImm(0));
3256 Instructions.push_back(NopInst);
3259 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3260 unsigned TrgReg, bool Is64Bit,
3261 SmallVectorImpl<MCInst> &Instructions) {
3262 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3266 void MipsAsmParser::createCpRestoreMemOp(
3267 bool IsLoad, int StackOffset, SMLoc IDLoc,
3268 SmallVectorImpl<MCInst> &Instructions) {
3270 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3271 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3272 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3273 MemInst.addOperand(MCOperand::createImm(StackOffset));
3275 // If the offset can not fit into 16 bits, we need to expand.
3276 if (!isInt<16>(StackOffset))
3277 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3279 Instructions.push_back(MemInst);
3282 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3283 // As described by the Mips32r2 spec, the registers Rd and Rs for
3284 // jalr.hb must be different.
3285 unsigned Opcode = Inst.getOpcode();
3287 if (Opcode == Mips::JALR_HB &&
3288 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3289 return Match_RequiresDifferentSrcAndDst;
3291 return Match_Success;
3294 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3295 OperandVector &Operands,
3297 uint64_t &ErrorInfo,
3298 bool MatchingInlineAsm) {
3301 SmallVector<MCInst, 8> Instructions;
3302 unsigned MatchResult =
3303 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3305 switch (MatchResult) {
3306 case Match_Success: {
3307 if (processInstruction(Inst, IDLoc, Instructions))
3309 for (unsigned i = 0; i < Instructions.size(); i++)
3310 Out.EmitInstruction(Instructions[i], STI);
3313 case Match_MissingFeature:
3314 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3316 case Match_InvalidOperand: {
3317 SMLoc ErrorLoc = IDLoc;
3318 if (ErrorInfo != ~0ULL) {
3319 if (ErrorInfo >= Operands.size())
3320 return Error(IDLoc, "too few operands for instruction");
3322 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3323 if (ErrorLoc == SMLoc())
3327 return Error(ErrorLoc, "invalid operand for instruction");
3329 case Match_MnemonicFail:
3330 return Error(IDLoc, "invalid instruction");
3331 case Match_RequiresDifferentSrcAndDst:
3332 return Error(IDLoc, "source and destination must be different");
3335 llvm_unreachable("Implement any new match types added!");
3338 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3339 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3340 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3341 ") without \".set noat\"");
3344 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3345 if (!AssemblerOptions.back()->isMacro())
3346 Warning(Loc, "macro instruction expanded into multiple instructions");
3350 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3351 SMRange Range, bool ShowColors) {
3352 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3353 Range, SMFixIt(Range, FixMsg),
3357 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3360 CC = StringSwitch<unsigned>(Name)
3396 if (!(isABI_N32() || isABI_N64()))
3399 if (12 <= CC && CC <= 15) {
3400 // Name is one of t4-t7
3401 AsmToken RegTok = getLexer().peekTok();
3402 SMRange RegRange = RegTok.getLocRange();
3404 StringRef FixedName = StringSwitch<StringRef>(Name)
3410 assert(FixedName != "" && "Register name is not one of t4-t7.");
3412 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3413 "Did you mean $" + FixedName + "?", RegRange);
3416 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3417 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3418 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3419 if (8 <= CC && CC <= 11)
3423 CC = StringSwitch<unsigned>(Name)
3435 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3438 CC = StringSwitch<unsigned>(Name)
3439 .Case("hwr_cpunum", 0)
3440 .Case("hwr_synci_step", 1)
3442 .Case("hwr_ccres", 3)
3443 .Case("hwr_ulr", 29)
3449 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3451 if (Name[0] == 'f') {
3452 StringRef NumString = Name.substr(1);
3454 if (NumString.getAsInteger(10, IntVal))
3455 return -1; // This is not an integer.
3456 if (IntVal > 31) // Maximum index for fpu register.
3463 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3465 if (Name.startswith("fcc")) {
3466 StringRef NumString = Name.substr(3);
3468 if (NumString.getAsInteger(10, IntVal))
3469 return -1; // This is not an integer.
3470 if (IntVal > 7) // There are only 8 fcc registers.
3477 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3479 if (Name.startswith("ac")) {
3480 StringRef NumString = Name.substr(2);
3482 if (NumString.getAsInteger(10, IntVal))
3483 return -1; // This is not an integer.
3484 if (IntVal > 3) // There are only 3 acc registers.
3491 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3494 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3503 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3506 CC = StringSwitch<unsigned>(Name)
3509 .Case("msaaccess", 2)
3511 .Case("msamodify", 4)
3512 .Case("msarequest", 5)
3514 .Case("msaunmap", 7)
3520 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3521 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3523 reportParseError(Loc,
3524 "pseudo-instruction requires $at, which is not available");
3527 unsigned AT = getReg(
3528 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3532 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3533 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3536 unsigned MipsAsmParser::getGPR(int RegNo) {
3537 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3541 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3543 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3546 return getReg(RegClass, RegNum);
3549 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3550 MCAsmParser &Parser = getParser();
3551 DEBUG(dbgs() << "parseOperand\n");
3553 // Check if the current operand has a custom associated parser, if so, try to
3554 // custom parse the operand, or fallback to the general approach.
3555 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3556 if (ResTy == MatchOperand_Success)
3558 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3559 // there was a match, but an error occurred, in which case, just return that
3560 // the operand parsing failed.
3561 if (ResTy == MatchOperand_ParseFail)
3564 DEBUG(dbgs() << ".. Generic Parser\n");
3566 switch (getLexer().getKind()) {
3568 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3570 case AsmToken::Dollar: {
3571 // Parse the register.
3572 SMLoc S = Parser.getTok().getLoc();
3574 // Almost all registers have been parsed by custom parsers. There is only
3575 // one exception to this. $zero (and it's alias $0) will reach this point
3576 // for div, divu, and similar instructions because it is not an operand
3577 // to the instruction definition but an explicit register. Special case
3578 // this situation for now.
3579 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3582 // Maybe it is a symbol reference.
3583 StringRef Identifier;
3584 if (Parser.parseIdentifier(Identifier))
3587 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3588 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3589 // Otherwise create a symbol reference.
3591 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3593 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3596 // Else drop to expression parsing.
3597 case AsmToken::LParen:
3598 case AsmToken::Minus:
3599 case AsmToken::Plus:
3600 case AsmToken::Integer:
3601 case AsmToken::Tilde:
3602 case AsmToken::String: {
3603 DEBUG(dbgs() << ".. generic integer\n");
3604 OperandMatchResultTy ResTy = parseImm(Operands);
3605 return ResTy != MatchOperand_Success;
3607 case AsmToken::Percent: {
3608 // It is a symbol reference or constant expression.
3609 const MCExpr *IdVal;
3610 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3611 if (parseRelocOperand(IdVal))
3614 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3616 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3618 } // case AsmToken::Percent
3619 } // switch(getLexer().getKind())
3623 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3624 StringRef RelocStr) {
3626 // Check the type of the expression.
3627 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3628 // It's a constant, evaluate reloc value.
3630 switch (getVariantKind(RelocStr)) {
3631 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3632 // Get the 1st 16-bits.
3633 Val = MCE->getValue() & 0xffff;
3635 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3636 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3637 // 16 bits being negative.
3638 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3640 case MCSymbolRefExpr::VK_Mips_HIGHER:
3641 // Get the 3rd 16-bits.
3642 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3644 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3645 // Get the 4th 16-bits.
3646 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3649 report_fatal_error("unsupported reloc value");
3651 return MCConstantExpr::create(Val, getContext());
3654 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3655 // It's a symbol, create a symbolic expression from the symbol.
3656 const MCSymbol *Symbol = &MSRE->getSymbol();
3657 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3658 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3662 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3663 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3665 // Try to create target expression.
3666 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3667 return MipsMCExpr::create(VK, Expr, getContext());
3669 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3670 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3671 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3675 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3676 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3677 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3680 // Just return the original expression.
3684 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3686 switch (Expr->getKind()) {
3687 case MCExpr::Constant:
3689 case MCExpr::SymbolRef:
3690 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3691 case MCExpr::Binary:
3692 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3693 if (!isEvaluated(BE->getLHS()))
3695 return isEvaluated(BE->getRHS());
3698 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3699 case MCExpr::Target:
3705 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3706 MCAsmParser &Parser = getParser();
3707 Parser.Lex(); // Eat the % token.
3708 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3709 if (Tok.isNot(AsmToken::Identifier))
3712 std::string Str = Tok.getIdentifier();
3714 Parser.Lex(); // Eat the identifier.
3715 // Now make an expression from the rest of the operand.
3716 const MCExpr *IdVal;
3719 if (getLexer().getKind() == AsmToken::LParen) {
3721 Parser.Lex(); // Eat the '(' token.
3722 if (getLexer().getKind() == AsmToken::Percent) {
3723 Parser.Lex(); // Eat the % token.
3724 const AsmToken &nextTok = Parser.getTok();
3725 if (nextTok.isNot(AsmToken::Identifier))
3728 Str += nextTok.getIdentifier();
3729 Parser.Lex(); // Eat the identifier.
3730 if (getLexer().getKind() != AsmToken::LParen)
3735 if (getParser().parseParenExpression(IdVal, EndLoc))
3738 while (getLexer().getKind() == AsmToken::RParen)
3739 Parser.Lex(); // Eat the ')' token.
3742 return true; // Parenthesis must follow the relocation operand.
3744 Res = evaluateRelocExpr(IdVal, Str);
3748 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3750 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3751 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3752 if (ResTy == MatchOperand_Success) {
3753 assert(Operands.size() == 1);
3754 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3755 StartLoc = Operand.getStartLoc();
3756 EndLoc = Operand.getEndLoc();
3758 // AFAIK, we only support numeric registers and named GPR's in CFI
3760 // Don't worry about eating tokens before failing. Using an unrecognised
3761 // register is a parse error.
3762 if (Operand.isGPRAsmReg()) {
3763 // Resolve to GPR32 or GPR64 appropriately.
3764 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3767 return (RegNo == (unsigned)-1);
3770 assert(Operands.size() == 0);
3771 return (RegNo == (unsigned)-1);
3774 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3775 MCAsmParser &Parser = getParser();
3778 unsigned NumOfLParen = 0;
3780 while (getLexer().getKind() == AsmToken::LParen) {
3785 switch (getLexer().getKind()) {
3788 case AsmToken::Identifier:
3789 case AsmToken::LParen:
3790 case AsmToken::Integer:
3791 case AsmToken::Minus:
3792 case AsmToken::Plus:
3794 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3796 Result = (getParser().parseExpression(Res));
3797 while (getLexer().getKind() == AsmToken::RParen)
3800 case AsmToken::Percent:
3801 Result = parseRelocOperand(Res);
3806 MipsAsmParser::OperandMatchResultTy
3807 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3808 MCAsmParser &Parser = getParser();
3809 DEBUG(dbgs() << "parseMemOperand\n");
3810 const MCExpr *IdVal = nullptr;
3812 bool isParenExpr = false;
3813 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3814 // First operand is the offset.
3815 S = Parser.getTok().getLoc();
3817 if (getLexer().getKind() == AsmToken::LParen) {
3822 if (getLexer().getKind() != AsmToken::Dollar) {
3823 if (parseMemOffset(IdVal, isParenExpr))
3824 return MatchOperand_ParseFail;
3826 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3827 if (Tok.isNot(AsmToken::LParen)) {
3828 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3829 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3831 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3832 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3833 return MatchOperand_Success;
3835 if (Tok.is(AsmToken::EndOfStatement)) {
3837 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3839 // Zero register assumed, add a memory operand with ZERO as its base.
3840 // "Base" will be managed by k_Memory.
3841 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3844 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3845 return MatchOperand_Success;
3847 Error(Parser.getTok().getLoc(), "'(' expected");
3848 return MatchOperand_ParseFail;
3851 Parser.Lex(); // Eat the '(' token.
3854 Res = parseAnyRegister(Operands);
3855 if (Res != MatchOperand_Success)
3858 if (Parser.getTok().isNot(AsmToken::RParen)) {
3859 Error(Parser.getTok().getLoc(), "')' expected");
3860 return MatchOperand_ParseFail;
3863 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3865 Parser.Lex(); // Eat the ')' token.
3868 IdVal = MCConstantExpr::create(0, getContext());
3870 // Replace the register operand with the memory operand.
3871 std::unique_ptr<MipsOperand> op(
3872 static_cast<MipsOperand *>(Operands.back().release()));
3873 // Remove the register from the operands.
3874 // "op" will be managed by k_Memory.
3875 Operands.pop_back();
3876 // Add the memory operand.
3877 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3879 if (IdVal->evaluateAsAbsolute(Imm))
3880 IdVal = MCConstantExpr::create(Imm, getContext());
3881 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3882 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3886 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3887 return MatchOperand_Success;
3890 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3891 MCAsmParser &Parser = getParser();
3892 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3894 SMLoc S = Parser.getTok().getLoc();
3896 if (Sym->isVariable())
3897 Expr = Sym->getVariableValue();
3900 if (Expr->getKind() == MCExpr::SymbolRef) {
3901 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3902 StringRef DefSymbol = Ref->getSymbol().getName();
3903 if (DefSymbol.startswith("$")) {
3904 OperandMatchResultTy ResTy =
3905 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3906 if (ResTy == MatchOperand_Success) {
3909 } else if (ResTy == MatchOperand_ParseFail)
3910 llvm_unreachable("Should never ParseFail");
3913 } else if (Expr->getKind() == MCExpr::Constant) {
3915 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3917 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3924 MipsAsmParser::OperandMatchResultTy
3925 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3926 StringRef Identifier,
3928 int Index = matchCPURegisterName(Identifier);
3930 Operands.push_back(MipsOperand::createGPRReg(
3931 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3932 return MatchOperand_Success;
3935 Index = matchHWRegsRegisterName(Identifier);
3937 Operands.push_back(MipsOperand::createHWRegsReg(
3938 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3939 return MatchOperand_Success;
3942 Index = matchFPURegisterName(Identifier);
3944 Operands.push_back(MipsOperand::createFGRReg(
3945 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3946 return MatchOperand_Success;
3949 Index = matchFCCRegisterName(Identifier);
3951 Operands.push_back(MipsOperand::createFCCReg(
3952 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3953 return MatchOperand_Success;
3956 Index = matchACRegisterName(Identifier);
3958 Operands.push_back(MipsOperand::createACCReg(
3959 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3960 return MatchOperand_Success;
3963 Index = matchMSA128RegisterName(Identifier);
3965 Operands.push_back(MipsOperand::createMSA128Reg(
3966 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3967 return MatchOperand_Success;
3970 Index = matchMSA128CtrlRegisterName(Identifier);
3972 Operands.push_back(MipsOperand::createMSACtrlReg(
3973 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3974 return MatchOperand_Success;
3977 return MatchOperand_NoMatch;
3980 MipsAsmParser::OperandMatchResultTy
3981 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3982 MCAsmParser &Parser = getParser();
3983 auto Token = Parser.getLexer().peekTok(false);
3985 if (Token.is(AsmToken::Identifier)) {
3986 DEBUG(dbgs() << ".. identifier\n");
3987 StringRef Identifier = Token.getIdentifier();
3988 OperandMatchResultTy ResTy =
3989 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3991 } else if (Token.is(AsmToken::Integer)) {
3992 DEBUG(dbgs() << ".. integer\n");
3993 Operands.push_back(MipsOperand::createNumericReg(
3994 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3996 return MatchOperand_Success;
3999 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4001 return MatchOperand_NoMatch;
4004 MipsAsmParser::OperandMatchResultTy
4005 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4006 MCAsmParser &Parser = getParser();
4007 DEBUG(dbgs() << "parseAnyRegister\n");
4009 auto Token = Parser.getTok();
4011 SMLoc S = Token.getLoc();
4013 if (Token.isNot(AsmToken::Dollar)) {
4014 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4015 if (Token.is(AsmToken::Identifier)) {
4016 if (searchSymbolAlias(Operands))
4017 return MatchOperand_Success;
4019 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4020 return MatchOperand_NoMatch;
4022 DEBUG(dbgs() << ".. $\n");
4024 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4025 if (ResTy == MatchOperand_Success) {
4027 Parser.Lex(); // identifier
4032 MipsAsmParser::OperandMatchResultTy
4033 MipsAsmParser::parseImm(OperandVector &Operands) {
4034 MCAsmParser &Parser = getParser();
4035 switch (getLexer().getKind()) {
4037 return MatchOperand_NoMatch;
4038 case AsmToken::LParen:
4039 case AsmToken::Minus:
4040 case AsmToken::Plus:
4041 case AsmToken::Integer:
4042 case AsmToken::Tilde:
4043 case AsmToken::String:
4047 const MCExpr *IdVal;
4048 SMLoc S = Parser.getTok().getLoc();
4049 if (getParser().parseExpression(IdVal))
4050 return MatchOperand_ParseFail;
4052 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4053 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4054 return MatchOperand_Success;
4057 MipsAsmParser::OperandMatchResultTy
4058 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4059 MCAsmParser &Parser = getParser();
4060 DEBUG(dbgs() << "parseJumpTarget\n");
4062 SMLoc S = getLexer().getLoc();
4064 // Integers and expressions are acceptable
4065 OperandMatchResultTy ResTy = parseImm(Operands);
4066 if (ResTy != MatchOperand_NoMatch)
4069 // Registers are a valid target and have priority over symbols.
4070 ResTy = parseAnyRegister(Operands);
4071 if (ResTy != MatchOperand_NoMatch)
4074 const MCExpr *Expr = nullptr;
4075 if (Parser.parseExpression(Expr)) {
4076 // We have no way of knowing if a symbol was consumed so we must ParseFail
4077 return MatchOperand_ParseFail;
4080 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4081 return MatchOperand_Success;
4084 MipsAsmParser::OperandMatchResultTy
4085 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4086 MCAsmParser &Parser = getParser();
4087 const MCExpr *IdVal;
4088 // If the first token is '$' we may have register operand.
4089 if (Parser.getTok().is(AsmToken::Dollar))
4090 return MatchOperand_NoMatch;
4091 SMLoc S = Parser.getTok().getLoc();
4092 if (getParser().parseExpression(IdVal))
4093 return MatchOperand_ParseFail;
4094 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4095 assert(MCE && "Unexpected MCExpr type.");
4096 int64_t Val = MCE->getValue();
4097 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4098 Operands.push_back(MipsOperand::CreateImm(
4099 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4100 return MatchOperand_Success;
4103 MipsAsmParser::OperandMatchResultTy
4104 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4105 MCAsmParser &Parser = getParser();
4106 switch (getLexer().getKind()) {
4108 return MatchOperand_NoMatch;
4109 case AsmToken::LParen:
4110 case AsmToken::Plus:
4111 case AsmToken::Minus:
4112 case AsmToken::Integer:
4117 SMLoc S = Parser.getTok().getLoc();
4119 if (getParser().parseExpression(Expr))
4120 return MatchOperand_ParseFail;
4123 if (!Expr->evaluateAsAbsolute(Val)) {
4124 Error(S, "expected immediate value");
4125 return MatchOperand_ParseFail;
4128 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4129 // and because the CPU always adds one to the immediate field, the allowed
4130 // range becomes 1..4. We'll only check the range here and will deal
4131 // with the addition/subtraction when actually decoding/encoding
4133 if (Val < 1 || Val > 4) {
4134 Error(S, "immediate not in range (1..4)");
4135 return MatchOperand_ParseFail;
4139 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4140 return MatchOperand_Success;
4143 MipsAsmParser::OperandMatchResultTy
4144 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4145 MCAsmParser &Parser = getParser();
4146 SmallVector<unsigned, 10> Regs;
4148 unsigned PrevReg = Mips::NoRegister;
4149 bool RegRange = false;
4150 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4152 if (Parser.getTok().isNot(AsmToken::Dollar))
4153 return MatchOperand_ParseFail;
4155 SMLoc S = Parser.getTok().getLoc();
4156 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4157 SMLoc E = getLexer().getLoc();
4158 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4159 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4161 // Remove last register operand because registers from register range
4162 // should be inserted first.
4163 if (RegNo == Mips::RA) {
4164 Regs.push_back(RegNo);
4166 unsigned TmpReg = PrevReg + 1;
4167 while (TmpReg <= RegNo) {
4168 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4169 Error(E, "invalid register operand");
4170 return MatchOperand_ParseFail;
4174 Regs.push_back(TmpReg++);
4180 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4181 (RegNo != Mips::RA)) {
4182 Error(E, "$16 or $31 expected");
4183 return MatchOperand_ParseFail;
4184 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4185 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4186 Error(E, "invalid register operand");
4187 return MatchOperand_ParseFail;
4188 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4189 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4190 Error(E, "consecutive register numbers expected");
4191 return MatchOperand_ParseFail;
4194 Regs.push_back(RegNo);
4197 if (Parser.getTok().is(AsmToken::Minus))
4200 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4201 !Parser.getTok().isNot(AsmToken::Comma)) {
4202 Error(E, "',' or '-' expected");
4203 return MatchOperand_ParseFail;
4206 Lex(); // Consume comma or minus
4207 if (Parser.getTok().isNot(AsmToken::Dollar))
4213 SMLoc E = Parser.getTok().getLoc();
4214 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4215 parseMemOperand(Operands);
4216 return MatchOperand_Success;
4219 MipsAsmParser::OperandMatchResultTy
4220 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4221 MCAsmParser &Parser = getParser();
4223 SMLoc S = Parser.getTok().getLoc();
4224 if (parseAnyRegister(Operands) != MatchOperand_Success)
4225 return MatchOperand_ParseFail;
4227 SMLoc E = Parser.getTok().getLoc();
4228 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4229 unsigned Reg = Op.getGPR32Reg();
4230 Operands.pop_back();
4231 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4232 return MatchOperand_Success;
4235 MipsAsmParser::OperandMatchResultTy
4236 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4237 MCAsmParser &Parser = getParser();
4238 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4239 SmallVector<unsigned, 10> Regs;
4241 if (Parser.getTok().isNot(AsmToken::Dollar))
4242 return MatchOperand_ParseFail;
4244 SMLoc S = Parser.getTok().getLoc();
4246 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4247 return MatchOperand_ParseFail;
4249 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4250 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4251 Regs.push_back(RegNo);
4253 SMLoc E = Parser.getTok().getLoc();
4254 if (Parser.getTok().isNot(AsmToken::Comma)) {
4255 Error(E, "',' expected");
4256 return MatchOperand_ParseFail;
4262 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4263 return MatchOperand_ParseFail;
4265 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4266 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4267 Regs.push_back(RegNo);
4269 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4271 return MatchOperand_Success;
4274 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4276 MCSymbolRefExpr::VariantKind VK =
4277 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4278 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4279 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4280 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4281 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4282 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4283 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4284 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4285 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4286 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4287 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4288 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4289 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4290 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4291 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4292 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4293 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4294 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4295 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4296 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4297 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4298 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4299 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4300 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4301 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4302 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4303 .Default(MCSymbolRefExpr::VK_None);
4305 assert(VK != MCSymbolRefExpr::VK_None);
4310 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4312 /// ::= '(', register, ')'
4313 /// handle it before we iterate so we don't get tripped up by the lack of
4315 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4316 MCAsmParser &Parser = getParser();
4317 if (getLexer().is(AsmToken::LParen)) {
4319 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4321 if (parseOperand(Operands, Name)) {
4322 SMLoc Loc = getLexer().getLoc();
4323 Parser.eatToEndOfStatement();
4324 return Error(Loc, "unexpected token in argument list");
4326 if (Parser.getTok().isNot(AsmToken::RParen)) {
4327 SMLoc Loc = getLexer().getLoc();
4328 Parser.eatToEndOfStatement();
4329 return Error(Loc, "unexpected token, expected ')'");
4332 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4338 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4339 /// either one of these.
4340 /// ::= '[', register, ']'
4341 /// ::= '[', integer, ']'
4342 /// handle it before we iterate so we don't get tripped up by the lack of
4344 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4345 OperandVector &Operands) {
4346 MCAsmParser &Parser = getParser();
4347 if (getLexer().is(AsmToken::LBrac)) {
4349 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4351 if (parseOperand(Operands, Name)) {
4352 SMLoc Loc = getLexer().getLoc();
4353 Parser.eatToEndOfStatement();
4354 return Error(Loc, "unexpected token in argument list");
4356 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4357 SMLoc Loc = getLexer().getLoc();
4358 Parser.eatToEndOfStatement();
4359 return Error(Loc, "unexpected token, expected ']'");
4362 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4368 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4369 SMLoc NameLoc, OperandVector &Operands) {
4370 MCAsmParser &Parser = getParser();
4371 DEBUG(dbgs() << "ParseInstruction\n");
4373 // We have reached first instruction, module directive are now forbidden.
4374 getTargetStreamer().forbidModuleDirective();
4376 // Check if we have valid mnemonic
4377 if (!mnemonicIsValid(Name, 0)) {
4378 Parser.eatToEndOfStatement();
4379 return Error(NameLoc, "unknown instruction");
4381 // First operand in MCInst is instruction mnemonic.
4382 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4384 // Read the remaining operands.
4385 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4386 // Read the first operand.
4387 if (parseOperand(Operands, Name)) {
4388 SMLoc Loc = getLexer().getLoc();
4389 Parser.eatToEndOfStatement();
4390 return Error(Loc, "unexpected token in argument list");
4392 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4394 // AFAIK, parenthesis suffixes are never on the first operand
4396 while (getLexer().is(AsmToken::Comma)) {
4397 Parser.Lex(); // Eat the comma.
4398 // Parse and remember the operand.
4399 if (parseOperand(Operands, Name)) {
4400 SMLoc Loc = getLexer().getLoc();
4401 Parser.eatToEndOfStatement();
4402 return Error(Loc, "unexpected token in argument list");
4404 // Parse bracket and parenthesis suffixes before we iterate
4405 if (getLexer().is(AsmToken::LBrac)) {
4406 if (parseBracketSuffix(Name, Operands))
4408 } else if (getLexer().is(AsmToken::LParen) &&
4409 parseParenSuffix(Name, Operands))
4413 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4414 SMLoc Loc = getLexer().getLoc();
4415 Parser.eatToEndOfStatement();
4416 return Error(Loc, "unexpected token in argument list");
4418 Parser.Lex(); // Consume the EndOfStatement.
4422 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4423 MCAsmParser &Parser = getParser();
4424 SMLoc Loc = getLexer().getLoc();
4425 Parser.eatToEndOfStatement();
4426 return Error(Loc, ErrorMsg);
4429 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4430 return Error(Loc, ErrorMsg);
4433 bool MipsAsmParser::parseSetNoAtDirective() {
4434 MCAsmParser &Parser = getParser();
4435 // Line should look like: ".set noat".
4437 // Set the $at register to $0.
4438 AssemblerOptions.back()->setATRegIndex(0);
4440 Parser.Lex(); // Eat "noat".
4442 // If this is not the end of the statement, report an error.
4443 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4444 reportParseError("unexpected token, expected end of statement");
4448 getTargetStreamer().emitDirectiveSetNoAt();
4449 Parser.Lex(); // Consume the EndOfStatement.
4453 bool MipsAsmParser::parseSetAtDirective() {
4454 // Line can be: ".set at", which sets $at to $1
4455 // or ".set at=$reg", which sets $at to $reg.
4456 MCAsmParser &Parser = getParser();
4457 Parser.Lex(); // Eat "at".
4459 if (getLexer().is(AsmToken::EndOfStatement)) {
4460 // No register was specified, so we set $at to $1.
4461 AssemblerOptions.back()->setATRegIndex(1);
4463 getTargetStreamer().emitDirectiveSetAt();
4464 Parser.Lex(); // Consume the EndOfStatement.
4468 if (getLexer().isNot(AsmToken::Equal)) {
4469 reportParseError("unexpected token, expected equals sign");
4472 Parser.Lex(); // Eat "=".
4474 if (getLexer().isNot(AsmToken::Dollar)) {
4475 if (getLexer().is(AsmToken::EndOfStatement)) {
4476 reportParseError("no register specified");
4479 reportParseError("unexpected token, expected dollar sign '$'");
4483 Parser.Lex(); // Eat "$".
4485 // Find out what "reg" is.
4487 const AsmToken &Reg = Parser.getTok();
4488 if (Reg.is(AsmToken::Identifier)) {
4489 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4490 } else if (Reg.is(AsmToken::Integer)) {
4491 AtRegNo = Reg.getIntVal();
4493 reportParseError("unexpected token, expected identifier or integer");
4497 // Check if $reg is a valid register. If it is, set $at to $reg.
4498 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4499 reportParseError("invalid register");
4502 Parser.Lex(); // Eat "reg".
4504 // If this is not the end of the statement, report an error.
4505 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4506 reportParseError("unexpected token, expected end of statement");
4510 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4512 Parser.Lex(); // Consume the EndOfStatement.
4516 bool MipsAsmParser::parseSetReorderDirective() {
4517 MCAsmParser &Parser = getParser();
4519 // If this is not the end of the statement, report an error.
4520 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4521 reportParseError("unexpected token, expected end of statement");
4524 AssemblerOptions.back()->setReorder();
4525 getTargetStreamer().emitDirectiveSetReorder();
4526 Parser.Lex(); // Consume the EndOfStatement.
4530 bool MipsAsmParser::parseSetNoReorderDirective() {
4531 MCAsmParser &Parser = getParser();
4533 // If this is not the end of the statement, report an error.
4534 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4535 reportParseError("unexpected token, expected end of statement");
4538 AssemblerOptions.back()->setNoReorder();
4539 getTargetStreamer().emitDirectiveSetNoReorder();
4540 Parser.Lex(); // Consume the EndOfStatement.
4544 bool MipsAsmParser::parseSetMacroDirective() {
4545 MCAsmParser &Parser = getParser();
4547 // If this is not the end of the statement, report an error.
4548 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4549 reportParseError("unexpected token, expected end of statement");
4552 AssemblerOptions.back()->setMacro();
4553 getTargetStreamer().emitDirectiveSetMacro();
4554 Parser.Lex(); // Consume the EndOfStatement.
4558 bool MipsAsmParser::parseSetNoMacroDirective() {
4559 MCAsmParser &Parser = getParser();
4561 // If this is not the end of the statement, report an error.
4562 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4563 reportParseError("unexpected token, expected end of statement");
4566 if (AssemblerOptions.back()->isReorder()) {
4567 reportParseError("`noreorder' must be set before `nomacro'");
4570 AssemblerOptions.back()->setNoMacro();
4571 getTargetStreamer().emitDirectiveSetNoMacro();
4572 Parser.Lex(); // Consume the EndOfStatement.
4576 bool MipsAsmParser::parseSetMsaDirective() {
4577 MCAsmParser &Parser = getParser();
4580 // If this is not the end of the statement, report an error.
4581 if (getLexer().isNot(AsmToken::EndOfStatement))
4582 return reportParseError("unexpected token, expected end of statement");
4584 setFeatureBits(Mips::FeatureMSA, "msa");
4585 getTargetStreamer().emitDirectiveSetMsa();
4589 bool MipsAsmParser::parseSetNoMsaDirective() {
4590 MCAsmParser &Parser = getParser();
4593 // If this is not the end of the statement, report an error.
4594 if (getLexer().isNot(AsmToken::EndOfStatement))
4595 return reportParseError("unexpected token, expected end of statement");
4597 clearFeatureBits(Mips::FeatureMSA, "msa");
4598 getTargetStreamer().emitDirectiveSetNoMsa();
4602 bool MipsAsmParser::parseSetNoDspDirective() {
4603 MCAsmParser &Parser = getParser();
4604 Parser.Lex(); // Eat "nodsp".
4606 // If this is not the end of the statement, report an error.
4607 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4608 reportParseError("unexpected token, expected end of statement");
4612 clearFeatureBits(Mips::FeatureDSP, "dsp");
4613 getTargetStreamer().emitDirectiveSetNoDsp();
4617 bool MipsAsmParser::parseSetMips16Directive() {
4618 MCAsmParser &Parser = getParser();
4619 Parser.Lex(); // Eat "mips16".
4621 // If this is not the end of the statement, report an error.
4622 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4623 reportParseError("unexpected token, expected end of statement");
4627 setFeatureBits(Mips::FeatureMips16, "mips16");
4628 getTargetStreamer().emitDirectiveSetMips16();
4629 Parser.Lex(); // Consume the EndOfStatement.
4633 bool MipsAsmParser::parseSetNoMips16Directive() {
4634 MCAsmParser &Parser = getParser();
4635 Parser.Lex(); // Eat "nomips16".
4637 // If this is not the end of the statement, report an error.
4638 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4639 reportParseError("unexpected token, expected end of statement");
4643 clearFeatureBits(Mips::FeatureMips16, "mips16");
4644 getTargetStreamer().emitDirectiveSetNoMips16();
4645 Parser.Lex(); // Consume the EndOfStatement.
4649 bool MipsAsmParser::parseSetFpDirective() {
4650 MCAsmParser &Parser = getParser();
4651 MipsABIFlagsSection::FpABIKind FpAbiVal;
4652 // Line can be: .set fp=32
4655 Parser.Lex(); // Eat fp token
4656 AsmToken Tok = Parser.getTok();
4657 if (Tok.isNot(AsmToken::Equal)) {
4658 reportParseError("unexpected token, expected equals sign '='");
4661 Parser.Lex(); // Eat '=' token.
4662 Tok = Parser.getTok();
4664 if (!parseFpABIValue(FpAbiVal, ".set"))
4667 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4668 reportParseError("unexpected token, expected end of statement");
4671 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4672 Parser.Lex(); // Consume the EndOfStatement.
4676 bool MipsAsmParser::parseSetOddSPRegDirective() {
4677 MCAsmParser &Parser = getParser();
4679 Parser.Lex(); // Eat "oddspreg".
4680 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4681 reportParseError("unexpected token, expected end of statement");
4685 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4686 getTargetStreamer().emitDirectiveSetOddSPReg();
4690 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4691 MCAsmParser &Parser = getParser();
4693 Parser.Lex(); // Eat "nooddspreg".
4694 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4695 reportParseError("unexpected token, expected end of statement");
4699 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4700 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4704 bool MipsAsmParser::parseSetPopDirective() {
4705 MCAsmParser &Parser = getParser();
4706 SMLoc Loc = getLexer().getLoc();
4709 if (getLexer().isNot(AsmToken::EndOfStatement))
4710 return reportParseError("unexpected token, expected end of statement");
4712 // Always keep an element on the options "stack" to prevent the user
4713 // from changing the initial options. This is how we remember them.
4714 if (AssemblerOptions.size() == 2)
4715 return reportParseError(Loc, ".set pop with no .set push");
4717 AssemblerOptions.pop_back();
4718 setAvailableFeatures(
4719 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4720 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4722 getTargetStreamer().emitDirectiveSetPop();
4726 bool MipsAsmParser::parseSetPushDirective() {
4727 MCAsmParser &Parser = getParser();
4729 if (getLexer().isNot(AsmToken::EndOfStatement))
4730 return reportParseError("unexpected token, expected end of statement");
4732 // Create a copy of the current assembler options environment and push it.
4733 AssemblerOptions.push_back(
4734 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4736 getTargetStreamer().emitDirectiveSetPush();
4740 bool MipsAsmParser::parseSetSoftFloatDirective() {
4741 MCAsmParser &Parser = getParser();
4743 if (getLexer().isNot(AsmToken::EndOfStatement))
4744 return reportParseError("unexpected token, expected end of statement");
4746 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4747 getTargetStreamer().emitDirectiveSetSoftFloat();
4751 bool MipsAsmParser::parseSetHardFloatDirective() {
4752 MCAsmParser &Parser = getParser();
4754 if (getLexer().isNot(AsmToken::EndOfStatement))
4755 return reportParseError("unexpected token, expected end of statement");
4757 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4758 getTargetStreamer().emitDirectiveSetHardFloat();
4762 bool MipsAsmParser::parseSetAssignment() {
4764 const MCExpr *Value;
4765 MCAsmParser &Parser = getParser();
4767 if (Parser.parseIdentifier(Name))
4768 reportParseError("expected identifier after .set");
4770 if (getLexer().isNot(AsmToken::Comma))
4771 return reportParseError("unexpected token, expected comma");
4774 if (Parser.parseExpression(Value))
4775 return reportParseError("expected valid expression after comma");
4777 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4778 Sym->setVariableValue(Value);
4783 bool MipsAsmParser::parseSetMips0Directive() {
4784 MCAsmParser &Parser = getParser();
4786 if (getLexer().isNot(AsmToken::EndOfStatement))
4787 return reportParseError("unexpected token, expected end of statement");
4789 // Reset assembler options to their initial values.
4790 setAvailableFeatures(
4791 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4792 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4793 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4795 getTargetStreamer().emitDirectiveSetMips0();
4799 bool MipsAsmParser::parseSetArchDirective() {
4800 MCAsmParser &Parser = getParser();
4802 if (getLexer().isNot(AsmToken::Equal))
4803 return reportParseError("unexpected token, expected equals sign");
4807 if (Parser.parseIdentifier(Arch))
4808 return reportParseError("expected arch identifier");
4810 StringRef ArchFeatureName =
4811 StringSwitch<StringRef>(Arch)
4812 .Case("mips1", "mips1")
4813 .Case("mips2", "mips2")
4814 .Case("mips3", "mips3")
4815 .Case("mips4", "mips4")
4816 .Case("mips5", "mips5")
4817 .Case("mips32", "mips32")
4818 .Case("mips32r2", "mips32r2")
4819 .Case("mips32r3", "mips32r3")
4820 .Case("mips32r5", "mips32r5")
4821 .Case("mips32r6", "mips32r6")
4822 .Case("mips64", "mips64")
4823 .Case("mips64r2", "mips64r2")
4824 .Case("mips64r3", "mips64r3")
4825 .Case("mips64r5", "mips64r5")
4826 .Case("mips64r6", "mips64r6")
4827 .Case("cnmips", "cnmips")
4828 .Case("r4000", "mips3") // This is an implementation of Mips3.
4831 if (ArchFeatureName.empty())
4832 return reportParseError("unsupported architecture");
4834 selectArch(ArchFeatureName);
4835 getTargetStreamer().emitDirectiveSetArch(Arch);
4839 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4840 MCAsmParser &Parser = getParser();
4842 if (getLexer().isNot(AsmToken::EndOfStatement))
4843 return reportParseError("unexpected token, expected end of statement");
4847 llvm_unreachable("Unimplemented feature");
4848 case Mips::FeatureDSP:
4849 setFeatureBits(Mips::FeatureDSP, "dsp");
4850 getTargetStreamer().emitDirectiveSetDsp();
4852 case Mips::FeatureMicroMips:
4853 getTargetStreamer().emitDirectiveSetMicroMips();
4855 case Mips::FeatureMips1:
4856 selectArch("mips1");
4857 getTargetStreamer().emitDirectiveSetMips1();
4859 case Mips::FeatureMips2:
4860 selectArch("mips2");
4861 getTargetStreamer().emitDirectiveSetMips2();
4863 case Mips::FeatureMips3:
4864 selectArch("mips3");
4865 getTargetStreamer().emitDirectiveSetMips3();
4867 case Mips::FeatureMips4:
4868 selectArch("mips4");
4869 getTargetStreamer().emitDirectiveSetMips4();
4871 case Mips::FeatureMips5:
4872 selectArch("mips5");
4873 getTargetStreamer().emitDirectiveSetMips5();
4875 case Mips::FeatureMips32:
4876 selectArch("mips32");
4877 getTargetStreamer().emitDirectiveSetMips32();
4879 case Mips::FeatureMips32r2:
4880 selectArch("mips32r2");
4881 getTargetStreamer().emitDirectiveSetMips32R2();
4883 case Mips::FeatureMips32r3:
4884 selectArch("mips32r3");
4885 getTargetStreamer().emitDirectiveSetMips32R3();
4887 case Mips::FeatureMips32r5:
4888 selectArch("mips32r5");
4889 getTargetStreamer().emitDirectiveSetMips32R5();
4891 case Mips::FeatureMips32r6:
4892 selectArch("mips32r6");
4893 getTargetStreamer().emitDirectiveSetMips32R6();
4895 case Mips::FeatureMips64:
4896 selectArch("mips64");
4897 getTargetStreamer().emitDirectiveSetMips64();
4899 case Mips::FeatureMips64r2:
4900 selectArch("mips64r2");
4901 getTargetStreamer().emitDirectiveSetMips64R2();
4903 case Mips::FeatureMips64r3:
4904 selectArch("mips64r3");
4905 getTargetStreamer().emitDirectiveSetMips64R3();
4907 case Mips::FeatureMips64r5:
4908 selectArch("mips64r5");
4909 getTargetStreamer().emitDirectiveSetMips64R5();
4911 case Mips::FeatureMips64r6:
4912 selectArch("mips64r6");
4913 getTargetStreamer().emitDirectiveSetMips64R6();
4919 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4920 MCAsmParser &Parser = getParser();
4921 if (getLexer().isNot(AsmToken::Comma)) {
4922 SMLoc Loc = getLexer().getLoc();
4923 Parser.eatToEndOfStatement();
4924 return Error(Loc, ErrorStr);
4927 Parser.Lex(); // Eat the comma.
4931 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4932 // In this class, it is only used for .cprestore.
4933 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4934 // MipsTargetELFStreamer and MipsAsmParser.
4935 bool MipsAsmParser::isPicAndNotNxxAbi() {
4936 return inPicMode() && !(isABI_N32() || isABI_N64());
4939 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4940 if (AssemblerOptions.back()->isReorder())
4941 Warning(Loc, ".cpload should be inside a noreorder section");
4943 if (inMips16Mode()) {
4944 reportParseError(".cpload is not supported in Mips16 mode");
4948 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4949 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4950 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4951 reportParseError("expected register containing function address");
4955 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4956 if (!RegOpnd.isGPRAsmReg()) {
4957 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4961 // If this is not the end of the statement, report an error.
4962 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4963 reportParseError("unexpected token, expected end of statement");
4967 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4971 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4972 MCAsmParser &Parser = getParser();
4974 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4975 // is used in non-PIC mode.
4977 if (inMips16Mode()) {
4978 reportParseError(".cprestore is not supported in Mips16 mode");
4982 // Get the stack offset value.
4983 const MCExpr *StackOffset;
4984 int64_t StackOffsetVal;
4985 if (Parser.parseExpression(StackOffset)) {
4986 reportParseError("expected stack offset value");
4990 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4991 reportParseError("stack offset is not an absolute expression");
4995 if (StackOffsetVal < 0) {
4996 Warning(Loc, ".cprestore with negative stack offset has no effect");
4997 IsCpRestoreSet = false;
4999 IsCpRestoreSet = true;
5000 CpRestoreOffset = StackOffsetVal;
5003 // If this is not the end of the statement, report an error.
5004 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5005 reportParseError("unexpected token, expected end of statement");
5009 // Store the $gp on the stack.
5010 SmallVector<MCInst, 3> StoreInsts;
5011 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5014 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
5015 Parser.Lex(); // Consume the EndOfStatement.
5019 bool MipsAsmParser::parseDirectiveCPSetup() {
5020 MCAsmParser &Parser = getParser();
5023 bool SaveIsReg = true;
5025 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5026 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5027 if (ResTy == MatchOperand_NoMatch) {
5028 reportParseError("expected register containing function address");
5029 Parser.eatToEndOfStatement();
5033 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5034 if (!FuncRegOpnd.isGPRAsmReg()) {
5035 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5036 Parser.eatToEndOfStatement();
5040 FuncReg = FuncRegOpnd.getGPR32Reg();
5043 if (!eatComma("unexpected token, expected comma"))
5046 ResTy = parseAnyRegister(TmpReg);
5047 if (ResTy == MatchOperand_NoMatch) {
5048 const MCExpr *OffsetExpr;
5050 SMLoc ExprLoc = getLexer().getLoc();
5052 if (Parser.parseExpression(OffsetExpr) ||
5053 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5054 reportParseError(ExprLoc, "expected save register or stack offset");
5055 Parser.eatToEndOfStatement();
5062 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5063 if (!SaveOpnd.isGPRAsmReg()) {
5064 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5065 Parser.eatToEndOfStatement();
5068 Save = SaveOpnd.getGPR32Reg();
5071 if (!eatComma("unexpected token, expected comma"))
5075 if (Parser.parseExpression(Expr)) {
5076 reportParseError("expected expression");
5080 if (Expr->getKind() != MCExpr::SymbolRef) {
5081 reportParseError("expected symbol");
5084 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5086 CpSaveLocation = Save;
5087 CpSaveLocationIsRegister = SaveIsReg;
5089 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5094 bool MipsAsmParser::parseDirectiveCPReturn() {
5095 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5096 CpSaveLocationIsRegister);
5100 bool MipsAsmParser::parseDirectiveNaN() {
5101 MCAsmParser &Parser = getParser();
5102 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5103 const AsmToken &Tok = Parser.getTok();
5105 if (Tok.getString() == "2008") {
5107 getTargetStreamer().emitDirectiveNaN2008();
5109 } else if (Tok.getString() == "legacy") {
5111 getTargetStreamer().emitDirectiveNaNLegacy();
5115 // If we don't recognize the option passed to the .nan
5116 // directive (e.g. no option or unknown option), emit an error.
5117 reportParseError("invalid option in .nan directive");
5121 bool MipsAsmParser::parseDirectiveSet() {
5122 MCAsmParser &Parser = getParser();
5123 // Get the next token.
5124 const AsmToken &Tok = Parser.getTok();
5126 if (Tok.getString() == "noat") {
5127 return parseSetNoAtDirective();
5128 } else if (Tok.getString() == "at") {
5129 return parseSetAtDirective();
5130 } else if (Tok.getString() == "arch") {
5131 return parseSetArchDirective();
5132 } else if (Tok.getString() == "fp") {
5133 return parseSetFpDirective();
5134 } else if (Tok.getString() == "oddspreg") {
5135 return parseSetOddSPRegDirective();
5136 } else if (Tok.getString() == "nooddspreg") {
5137 return parseSetNoOddSPRegDirective();
5138 } else if (Tok.getString() == "pop") {
5139 return parseSetPopDirective();
5140 } else if (Tok.getString() == "push") {
5141 return parseSetPushDirective();
5142 } else if (Tok.getString() == "reorder") {
5143 return parseSetReorderDirective();
5144 } else if (Tok.getString() == "noreorder") {
5145 return parseSetNoReorderDirective();
5146 } else if (Tok.getString() == "macro") {
5147 return parseSetMacroDirective();
5148 } else if (Tok.getString() == "nomacro") {
5149 return parseSetNoMacroDirective();
5150 } else if (Tok.getString() == "mips16") {
5151 return parseSetMips16Directive();
5152 } else if (Tok.getString() == "nomips16") {
5153 return parseSetNoMips16Directive();
5154 } else if (Tok.getString() == "nomicromips") {
5155 getTargetStreamer().emitDirectiveSetNoMicroMips();
5156 Parser.eatToEndOfStatement();
5158 } else if (Tok.getString() == "micromips") {
5159 return parseSetFeature(Mips::FeatureMicroMips);
5160 } else if (Tok.getString() == "mips0") {
5161 return parseSetMips0Directive();
5162 } else if (Tok.getString() == "mips1") {
5163 return parseSetFeature(Mips::FeatureMips1);
5164 } else if (Tok.getString() == "mips2") {
5165 return parseSetFeature(Mips::FeatureMips2);
5166 } else if (Tok.getString() == "mips3") {
5167 return parseSetFeature(Mips::FeatureMips3);
5168 } else if (Tok.getString() == "mips4") {
5169 return parseSetFeature(Mips::FeatureMips4);
5170 } else if (Tok.getString() == "mips5") {
5171 return parseSetFeature(Mips::FeatureMips5);
5172 } else if (Tok.getString() == "mips32") {
5173 return parseSetFeature(Mips::FeatureMips32);
5174 } else if (Tok.getString() == "mips32r2") {
5175 return parseSetFeature(Mips::FeatureMips32r2);
5176 } else if (Tok.getString() == "mips32r3") {
5177 return parseSetFeature(Mips::FeatureMips32r3);
5178 } else if (Tok.getString() == "mips32r5") {
5179 return parseSetFeature(Mips::FeatureMips32r5);
5180 } else if (Tok.getString() == "mips32r6") {
5181 return parseSetFeature(Mips::FeatureMips32r6);
5182 } else if (Tok.getString() == "mips64") {
5183 return parseSetFeature(Mips::FeatureMips64);
5184 } else if (Tok.getString() == "mips64r2") {
5185 return parseSetFeature(Mips::FeatureMips64r2);
5186 } else if (Tok.getString() == "mips64r3") {
5187 return parseSetFeature(Mips::FeatureMips64r3);
5188 } else if (Tok.getString() == "mips64r5") {
5189 return parseSetFeature(Mips::FeatureMips64r5);
5190 } else if (Tok.getString() == "mips64r6") {
5191 return parseSetFeature(Mips::FeatureMips64r6);
5192 } else if (Tok.getString() == "dsp") {
5193 return parseSetFeature(Mips::FeatureDSP);
5194 } else if (Tok.getString() == "nodsp") {
5195 return parseSetNoDspDirective();
5196 } else if (Tok.getString() == "msa") {
5197 return parseSetMsaDirective();
5198 } else if (Tok.getString() == "nomsa") {
5199 return parseSetNoMsaDirective();
5200 } else if (Tok.getString() == "softfloat") {
5201 return parseSetSoftFloatDirective();
5202 } else if (Tok.getString() == "hardfloat") {
5203 return parseSetHardFloatDirective();
5205 // It is just an identifier, look for an assignment.
5206 parseSetAssignment();
5213 /// parseDataDirective
5214 /// ::= .word [ expression (, expression)* ]
5215 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5216 MCAsmParser &Parser = getParser();
5217 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5219 const MCExpr *Value;
5220 if (getParser().parseExpression(Value))
5223 getParser().getStreamer().EmitValue(Value, Size);
5225 if (getLexer().is(AsmToken::EndOfStatement))
5228 if (getLexer().isNot(AsmToken::Comma))
5229 return Error(L, "unexpected token, expected comma");
5238 /// parseDirectiveGpWord
5239 /// ::= .gpword local_sym
5240 bool MipsAsmParser::parseDirectiveGpWord() {
5241 MCAsmParser &Parser = getParser();
5242 const MCExpr *Value;
5243 // EmitGPRel32Value requires an expression, so we are using base class
5244 // method to evaluate the expression.
5245 if (getParser().parseExpression(Value))
5247 getParser().getStreamer().EmitGPRel32Value(Value);
5249 if (getLexer().isNot(AsmToken::EndOfStatement))
5250 return Error(getLexer().getLoc(),
5251 "unexpected token, expected end of statement");
5252 Parser.Lex(); // Eat EndOfStatement token.
5256 /// parseDirectiveGpDWord
5257 /// ::= .gpdword local_sym
5258 bool MipsAsmParser::parseDirectiveGpDWord() {
5259 MCAsmParser &Parser = getParser();
5260 const MCExpr *Value;
5261 // EmitGPRel64Value requires an expression, so we are using base class
5262 // method to evaluate the expression.
5263 if (getParser().parseExpression(Value))
5265 getParser().getStreamer().EmitGPRel64Value(Value);
5267 if (getLexer().isNot(AsmToken::EndOfStatement))
5268 return Error(getLexer().getLoc(),
5269 "unexpected token, expected end of statement");
5270 Parser.Lex(); // Eat EndOfStatement token.
5274 bool MipsAsmParser::parseDirectiveOption() {
5275 MCAsmParser &Parser = getParser();
5276 // Get the option token.
5277 AsmToken Tok = Parser.getTok();
5278 // At the moment only identifiers are supported.
5279 if (Tok.isNot(AsmToken::Identifier)) {
5280 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5281 Parser.eatToEndOfStatement();
5285 StringRef Option = Tok.getIdentifier();
5287 if (Option == "pic0") {
5288 // MipsAsmParser needs to know if the current PIC mode changes.
5289 IsPicEnabled = false;
5291 getTargetStreamer().emitDirectiveOptionPic0();
5293 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5294 Error(Parser.getTok().getLoc(),
5295 "unexpected token, expected end of statement");
5296 Parser.eatToEndOfStatement();
5301 if (Option == "pic2") {
5302 // MipsAsmParser needs to know if the current PIC mode changes.
5303 IsPicEnabled = true;
5305 getTargetStreamer().emitDirectiveOptionPic2();
5307 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5308 Error(Parser.getTok().getLoc(),
5309 "unexpected token, expected end of statement");
5310 Parser.eatToEndOfStatement();
5316 Warning(Parser.getTok().getLoc(),
5317 "unknown option, expected 'pic0' or 'pic2'");
5318 Parser.eatToEndOfStatement();
5322 /// parseInsnDirective
5324 bool MipsAsmParser::parseInsnDirective() {
5325 // If this is not the end of the statement, report an error.
5326 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5327 reportParseError("unexpected token, expected end of statement");
5331 // The actual label marking happens in
5332 // MipsELFStreamer::createPendingLabelRelocs().
5333 getTargetStreamer().emitDirectiveInsn();
5335 getParser().Lex(); // Eat EndOfStatement token.
5339 /// parseDirectiveModule
5340 /// ::= .module oddspreg
5341 /// ::= .module nooddspreg
5342 /// ::= .module fp=value
5343 /// ::= .module softfloat
5344 /// ::= .module hardfloat
5345 bool MipsAsmParser::parseDirectiveModule() {
5346 MCAsmParser &Parser = getParser();
5347 MCAsmLexer &Lexer = getLexer();
5348 SMLoc L = Lexer.getLoc();
5350 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5351 // TODO : get a better message.
5352 reportParseError(".module directive must appear before any code");
5357 if (Parser.parseIdentifier(Option)) {
5358 reportParseError("expected .module option identifier");
5362 if (Option == "oddspreg") {
5363 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5365 // Synchronize the abiflags information with the FeatureBits information we
5367 getTargetStreamer().updateABIInfo(*this);
5369 // If printing assembly, use the recently updated abiflags information.
5370 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5371 // emitted at the end).
5372 getTargetStreamer().emitDirectiveModuleOddSPReg();
5374 // If this is not the end of the statement, report an error.
5375 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5376 reportParseError("unexpected token, expected end of statement");
5380 return false; // parseDirectiveModule has finished successfully.
5381 } else if (Option == "nooddspreg") {
5383 Error(L, "'.module nooddspreg' requires the O32 ABI");
5387 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5389 // Synchronize the abiflags information with the FeatureBits information we
5391 getTargetStreamer().updateABIInfo(*this);
5393 // If printing assembly, use the recently updated abiflags information.
5394 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5395 // emitted at the end).
5396 getTargetStreamer().emitDirectiveModuleOddSPReg();
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 == "fp") {
5406 return parseDirectiveModuleFP();
5407 } else if (Option == "softfloat") {
5408 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5410 // Synchronize the ABI Flags information with the FeatureBits information we
5412 getTargetStreamer().updateABIInfo(*this);
5414 // If printing assembly, use the recently updated ABI Flags information.
5415 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5417 getTargetStreamer().emitDirectiveModuleSoftFloat();
5419 // If this is not the end of the statement, report an error.
5420 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5421 reportParseError("unexpected token, expected end of statement");
5425 return false; // parseDirectiveModule has finished successfully.
5426 } else if (Option == "hardfloat") {
5427 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5429 // Synchronize the ABI Flags information with the FeatureBits information we
5431 getTargetStreamer().updateABIInfo(*this);
5433 // If printing assembly, use the recently updated ABI Flags information.
5434 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5436 getTargetStreamer().emitDirectiveModuleHardFloat();
5438 // If this is not the end of the statement, report an error.
5439 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5440 reportParseError("unexpected token, expected end of statement");
5444 return false; // parseDirectiveModule has finished successfully.
5446 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5450 /// parseDirectiveModuleFP
5454 bool MipsAsmParser::parseDirectiveModuleFP() {
5455 MCAsmParser &Parser = getParser();
5456 MCAsmLexer &Lexer = getLexer();
5458 if (Lexer.isNot(AsmToken::Equal)) {
5459 reportParseError("unexpected token, expected equals sign '='");
5462 Parser.Lex(); // Eat '=' token.
5464 MipsABIFlagsSection::FpABIKind FpABI;
5465 if (!parseFpABIValue(FpABI, ".module"))
5468 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5469 reportParseError("unexpected token, expected end of statement");
5473 // Synchronize the abiflags information with the FeatureBits information we
5475 getTargetStreamer().updateABIInfo(*this);
5477 // If printing assembly, use the recently updated abiflags information.
5478 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5479 // emitted at the end).
5480 getTargetStreamer().emitDirectiveModuleFP();
5482 Parser.Lex(); // Consume the EndOfStatement.
5486 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5487 StringRef Directive) {
5488 MCAsmParser &Parser = getParser();
5489 MCAsmLexer &Lexer = getLexer();
5490 bool ModuleLevelOptions = Directive == ".module";
5492 if (Lexer.is(AsmToken::Identifier)) {
5493 StringRef Value = Parser.getTok().getString();
5496 if (Value != "xx") {
5497 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5502 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5506 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5507 if (ModuleLevelOptions) {
5508 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5509 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5511 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5512 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5517 if (Lexer.is(AsmToken::Integer)) {
5518 unsigned Value = Parser.getTok().getIntVal();
5521 if (Value != 32 && Value != 64) {
5522 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5528 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5532 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5533 if (ModuleLevelOptions) {
5534 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5535 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5537 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5538 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5541 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5542 if (ModuleLevelOptions) {
5543 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5544 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5546 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5547 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5557 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5558 MCAsmParser &Parser = getParser();
5559 StringRef IDVal = DirectiveID.getString();
5561 if (IDVal == ".cpload")
5562 return parseDirectiveCpLoad(DirectiveID.getLoc());
5563 if (IDVal == ".cprestore")
5564 return parseDirectiveCpRestore(DirectiveID.getLoc());
5565 if (IDVal == ".dword") {
5566 parseDataDirective(8, DirectiveID.getLoc());
5569 if (IDVal == ".ent") {
5570 StringRef SymbolName;
5572 if (Parser.parseIdentifier(SymbolName)) {
5573 reportParseError("expected identifier after .ent");
5577 // There's an undocumented extension that allows an integer to
5578 // follow the name of the procedure which AFAICS is ignored by GAS.
5579 // Example: .ent foo,2
5580 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5581 if (getLexer().isNot(AsmToken::Comma)) {
5582 // Even though we accept this undocumented extension for compatibility
5583 // reasons, the additional integer argument does not actually change
5584 // the behaviour of the '.ent' directive, so we would like to discourage
5585 // its use. We do this by not referring to the extended version in
5586 // error messages which are not directly related to its use.
5587 reportParseError("unexpected token, expected end of statement");
5590 Parser.Lex(); // Eat the comma.
5591 const MCExpr *DummyNumber;
5592 int64_t DummyNumberVal;
5593 // If the user was explicitly trying to use the extended version,
5594 // we still give helpful extension-related error messages.
5595 if (Parser.parseExpression(DummyNumber)) {
5596 reportParseError("expected number after comma");
5599 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5600 reportParseError("expected an absolute expression after comma");
5605 // If this is not the end of the statement, report an error.
5606 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5607 reportParseError("unexpected token, expected end of statement");
5611 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5613 getTargetStreamer().emitDirectiveEnt(*Sym);
5615 IsCpRestoreSet = false;
5619 if (IDVal == ".end") {
5620 StringRef SymbolName;
5622 if (Parser.parseIdentifier(SymbolName)) {
5623 reportParseError("expected identifier after .end");
5627 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5628 reportParseError("unexpected token, expected end of statement");
5632 if (CurrentFn == nullptr) {
5633 reportParseError(".end used without .ent");
5637 if ((SymbolName != CurrentFn->getName())) {
5638 reportParseError(".end symbol does not match .ent symbol");
5642 getTargetStreamer().emitDirectiveEnd(SymbolName);
5643 CurrentFn = nullptr;
5644 IsCpRestoreSet = false;
5648 if (IDVal == ".frame") {
5649 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5650 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5651 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5652 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5653 reportParseError("expected stack register");
5657 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5658 if (!StackRegOpnd.isGPRAsmReg()) {
5659 reportParseError(StackRegOpnd.getStartLoc(),
5660 "expected general purpose register");
5663 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5665 if (Parser.getTok().is(AsmToken::Comma))
5668 reportParseError("unexpected token, expected comma");
5672 // Parse the frame size.
5673 const MCExpr *FrameSize;
5674 int64_t FrameSizeVal;
5676 if (Parser.parseExpression(FrameSize)) {
5677 reportParseError("expected frame size value");
5681 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5682 reportParseError("frame size not an absolute expression");
5686 if (Parser.getTok().is(AsmToken::Comma))
5689 reportParseError("unexpected token, expected comma");
5693 // Parse the return register.
5695 ResTy = parseAnyRegister(TmpReg);
5696 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5697 reportParseError("expected return register");
5701 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5702 if (!ReturnRegOpnd.isGPRAsmReg()) {
5703 reportParseError(ReturnRegOpnd.getStartLoc(),
5704 "expected general purpose register");
5708 // If this is not the end of the statement, report an error.
5709 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5710 reportParseError("unexpected token, expected end of statement");
5714 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5715 ReturnRegOpnd.getGPR32Reg());
5716 IsCpRestoreSet = false;
5720 if (IDVal == ".set") {
5721 return parseDirectiveSet();
5724 if (IDVal == ".mask" || IDVal == ".fmask") {
5725 // .mask bitmask, frame_offset
5726 // bitmask: One bit for each register used.
5727 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5728 // first register is expected to be saved.
5730 // .mask 0x80000000, -4
5731 // .fmask 0x80000000, -4
5734 // Parse the bitmask
5735 const MCExpr *BitMask;
5738 if (Parser.parseExpression(BitMask)) {
5739 reportParseError("expected bitmask value");
5743 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5744 reportParseError("bitmask not an absolute expression");
5748 if (Parser.getTok().is(AsmToken::Comma))
5751 reportParseError("unexpected token, expected comma");
5755 // Parse the frame_offset
5756 const MCExpr *FrameOffset;
5757 int64_t FrameOffsetVal;
5759 if (Parser.parseExpression(FrameOffset)) {
5760 reportParseError("expected frame offset value");
5764 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5765 reportParseError("frame offset not an absolute expression");
5769 // If this is not the end of the statement, report an error.
5770 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5771 reportParseError("unexpected token, expected end of statement");
5775 if (IDVal == ".mask")
5776 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5778 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5782 if (IDVal == ".nan")
5783 return parseDirectiveNaN();
5785 if (IDVal == ".gpword") {
5786 parseDirectiveGpWord();
5790 if (IDVal == ".gpdword") {
5791 parseDirectiveGpDWord();
5795 if (IDVal == ".word") {
5796 parseDataDirective(4, DirectiveID.getLoc());
5800 if (IDVal == ".option")
5801 return parseDirectiveOption();
5803 if (IDVal == ".abicalls") {
5804 getTargetStreamer().emitDirectiveAbiCalls();
5805 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5806 Error(Parser.getTok().getLoc(),
5807 "unexpected token, expected end of statement");
5809 Parser.eatToEndOfStatement();
5814 if (IDVal == ".cpsetup")
5815 return parseDirectiveCPSetup();
5817 if (IDVal == ".cpreturn")
5818 return parseDirectiveCPReturn();
5820 if (IDVal == ".module")
5821 return parseDirectiveModule();
5823 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5824 return parseInternalDirectiveReallowModule();
5826 if (IDVal == ".insn")
5827 return parseInsnDirective();
5832 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5833 // If this is not the end of the statement, report an error.
5834 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5835 reportParseError("unexpected token, expected end of statement");
5839 getTargetStreamer().reallowModuleDirective();
5841 getParser().Lex(); // Eat EndOfStatement token.
5845 extern "C" void LLVMInitializeMipsAsmParser() {
5846 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5847 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5848 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5849 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5852 #define GET_REGISTER_MATCHER
5853 #define GET_MATCHER_IMPLEMENTATION
5854 #include "MipsGenAsmMatcher.inc"