1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCParser/MCAsmLexer.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCTargetAsmParser.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
38 #define DEBUG_TYPE "mips-asm-parser"
45 class MipsAssemblerOptions {
47 MipsAssemblerOptions(const FeatureBitset &Features_) :
48 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
50 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
51 ATReg = Opts->getATRegIndex();
52 Reorder = Opts->isReorder();
53 Macro = Opts->isMacro();
54 Features = Opts->getFeatures();
57 unsigned getATRegIndex() const { return ATReg; }
58 bool setATRegIndex(unsigned Reg) {
66 bool isReorder() const { return Reorder; }
67 void setReorder() { Reorder = true; }
68 void setNoReorder() { Reorder = false; }
70 bool isMacro() const { return Macro; }
71 void setMacro() { Macro = true; }
72 void setNoMacro() { Macro = false; }
74 const FeatureBitset &getFeatures() const { return Features; }
75 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
77 // Set of features that are either architecture features or referenced
78 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
79 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
80 // The reason we need this mask is explained in the selectArch function.
81 // FIXME: Ideally we would like TableGen to generate this information.
82 static const FeatureBitset AllArchRelatedMask;
88 FeatureBitset Features;
92 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
93 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
94 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
95 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
96 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
97 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
98 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
99 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
100 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
104 class MipsAsmParser : public MCTargetAsmParser {
105 MipsTargetStreamer &getTargetStreamer() {
106 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
107 return static_cast<MipsTargetStreamer &>(TS);
110 MCSubtargetInfo &STI;
112 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
113 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
114 // nullptr, which indicates that no function is currently
115 // selected. This usually happens after an '.end func'
121 unsigned CpSaveLocation;
122 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
123 bool CpSaveLocationIsRegister;
125 // Print a warning along with its fix-it message at the given range.
126 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
127 SMRange Range, bool ShowColors = true);
129 #define GET_ASSEMBLER_HEADER
130 #include "MipsGenAsmMatcher.inc"
132 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
134 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
135 OperandVector &Operands, MCStreamer &Out,
137 bool MatchingInlineAsm) override;
139 /// Parse a register as used in CFI directives
140 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
142 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
144 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
146 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
147 SMLoc NameLoc, OperandVector &Operands) override;
149 bool ParseDirective(AsmToken DirectiveID) override;
151 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
153 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
154 StringRef Identifier, SMLoc S);
155 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
157 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
158 OperandMatchResultTy parseImm(OperandVector &Operands);
159 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
160 OperandMatchResultTy parseInvNum(OperandVector &Operands);
161 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
163 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
164 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
166 bool searchSymbolAlias(OperandVector &Operands);
168 bool parseOperand(OperandVector &, StringRef Mnemonic);
170 enum MacroExpanderResultTy {
176 // Expands assembly pseudo instructions.
177 MacroExpanderResultTy
178 tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
179 SmallVectorImpl<MCInst> &Instructions);
181 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
182 SmallVectorImpl<MCInst> &Instructions);
184 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
185 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
189 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
195 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
196 const MCOperand &Offset, bool Is32BitAddress,
197 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
199 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
200 SmallVectorImpl<MCInst> &Instructions);
202 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
206 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
207 SmallVectorImpl<MCInst> &Instructions);
209 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
210 SmallVectorImpl<MCInst> &Instructions);
212 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
213 SmallVectorImpl<MCInst> &Instructions);
215 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
216 SmallVectorImpl<MCInst> &Instructions);
218 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
222 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
223 SmallVectorImpl<MCInst> &Instructions);
225 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
226 SmallVectorImpl<MCInst> &Instructions);
228 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
229 SmallVectorImpl<MCInst> &Instructions);
231 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
232 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
234 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
235 SmallVectorImpl<MCInst> &Instructions);
237 bool reportParseError(Twine ErrorMsg);
238 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
240 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
241 bool parseRelocOperand(const MCExpr *&Res);
243 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
245 bool isEvaluated(const MCExpr *Expr);
246 bool parseSetMips0Directive();
247 bool parseSetArchDirective();
248 bool parseSetFeature(uint64_t Feature);
249 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
250 bool parseDirectiveCpLoad(SMLoc Loc);
251 bool parseDirectiveCpRestore(SMLoc Loc);
252 bool parseDirectiveCPSetup();
253 bool parseDirectiveCPReturn();
254 bool parseDirectiveNaN();
255 bool parseDirectiveSet();
256 bool parseDirectiveOption();
257 bool parseInsnDirective();
259 bool parseSetAtDirective();
260 bool parseSetNoAtDirective();
261 bool parseSetMacroDirective();
262 bool parseSetNoMacroDirective();
263 bool parseSetMsaDirective();
264 bool parseSetNoMsaDirective();
265 bool parseSetNoDspDirective();
266 bool parseSetReorderDirective();
267 bool parseSetNoReorderDirective();
268 bool parseSetMips16Directive();
269 bool parseSetNoMips16Directive();
270 bool parseSetFpDirective();
271 bool parseSetOddSPRegDirective();
272 bool parseSetNoOddSPRegDirective();
273 bool parseSetPopDirective();
274 bool parseSetPushDirective();
275 bool parseSetSoftFloatDirective();
276 bool parseSetHardFloatDirective();
278 bool parseSetAssignment();
280 bool parseDataDirective(unsigned Size, SMLoc L);
281 bool parseDirectiveGpWord();
282 bool parseDirectiveGpDWord();
283 bool parseDirectiveModule();
284 bool parseDirectiveModuleFP();
285 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
286 StringRef Directive);
288 bool parseInternalDirectiveReallowModule();
290 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
292 bool eatComma(StringRef ErrorStr);
294 int matchCPURegisterName(StringRef Symbol);
296 int matchHWRegsRegisterName(StringRef Symbol);
298 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
300 int matchFPURegisterName(StringRef Name);
302 int matchFCCRegisterName(StringRef Name);
304 int matchACRegisterName(StringRef Name);
306 int matchMSA128RegisterName(StringRef Name);
308 int matchMSA128CtrlRegisterName(StringRef Name);
310 unsigned getReg(int RC, int RegNo);
312 unsigned getGPR(int RegNo);
314 /// Returns the internal register number for the current AT. Also checks if
315 /// the current AT is unavailable (set to $0) and gives an error if it is.
316 /// This should be used in pseudo-instruction expansions which need AT.
317 unsigned getATReg(SMLoc Loc);
319 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
320 SmallVectorImpl<MCInst> &Instructions);
322 // Helper function that checks if the value of a vector index is within the
323 // boundaries of accepted values for each RegisterKind
324 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
325 bool validateMSAIndex(int Val, int RegKind);
327 // Selects a new architecture by updating the FeatureBits with the necessary
328 // info including implied dependencies.
329 // Internally, it clears all the feature bits related to *any* architecture
330 // and selects the new one using the ToggleFeature functionality of the
331 // MCSubtargetInfo object that handles implied dependencies. The reason we
332 // clear all the arch related bits manually is because ToggleFeature only
333 // clears the features that imply the feature being cleared and not the
334 // features implied by the feature being cleared. This is easier to see
336 // --------------------------------------------------
337 // | Feature | Implies |
338 // | -------------------------------------------------|
339 // | FeatureMips1 | None |
340 // | FeatureMips2 | FeatureMips1 |
341 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
342 // | FeatureMips4 | FeatureMips3 |
344 // --------------------------------------------------
346 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
347 // FeatureMipsGP64 | FeatureMips1)
348 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
349 void selectArch(StringRef ArchFeature) {
350 FeatureBitset FeatureBits = STI.getFeatureBits();
351 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
352 STI.setFeatureBits(FeatureBits);
353 setAvailableFeatures(
354 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
355 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
358 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
359 if (!(STI.getFeatureBits()[Feature])) {
360 setAvailableFeatures(
361 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
362 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
366 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
367 if (STI.getFeatureBits()[Feature]) {
368 setAvailableFeatures(
369 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
370 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
374 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
375 setFeatureBits(Feature, FeatureString);
376 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
379 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
380 clearFeatureBits(Feature, FeatureString);
381 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
385 enum MipsMatchResultTy {
386 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
387 #define GET_OPERAND_DIAGNOSTIC_TYPES
388 #include "MipsGenAsmMatcher.inc"
389 #undef GET_OPERAND_DIAGNOSTIC_TYPES
393 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
394 const MCInstrInfo &MII, const MCTargetOptions &Options)
395 : MCTargetAsmParser(Options), STI(sti),
396 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
397 sti.getCPU(), Options)) {
398 MCAsmParserExtension::Initialize(parser);
400 parser.addAliasForDirective(".asciiz", ".asciz");
402 // Initialize the set of available features.
403 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
405 // Remember the initial assembler options. The user can not modify these.
406 AssemblerOptions.push_back(
407 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
409 // Create an assembler options environment for the user to modify.
410 AssemblerOptions.push_back(
411 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
413 getTargetStreamer().updateABIInfo(*this);
415 if (!isABI_O32() && !useOddSPReg() != 0)
416 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
421 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
423 IsCpRestoreSet = false;
424 CpRestoreOffset = -1;
426 Triple TheTriple(sti.getTargetTriple());
427 if ((TheTriple.getArch() == Triple::mips) ||
428 (TheTriple.getArch() == Triple::mips64))
429 IsLittleEndian = false;
431 IsLittleEndian = true;
434 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
435 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
437 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
438 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
439 const MipsABIInfo &getABI() const { return ABI; }
440 bool isABI_N32() const { return ABI.IsN32(); }
441 bool isABI_N64() const { return ABI.IsN64(); }
442 bool isABI_O32() const { return ABI.IsO32(); }
443 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
445 bool useOddSPReg() const {
446 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
449 bool inMicroMipsMode() const {
450 return STI.getFeatureBits()[Mips::FeatureMicroMips];
452 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
453 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
454 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
455 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
456 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
457 bool hasMips32() const {
458 return STI.getFeatureBits()[Mips::FeatureMips32];
460 bool hasMips64() const {
461 return STI.getFeatureBits()[Mips::FeatureMips64];
463 bool hasMips32r2() const {
464 return STI.getFeatureBits()[Mips::FeatureMips32r2];
466 bool hasMips64r2() const {
467 return STI.getFeatureBits()[Mips::FeatureMips64r2];
469 bool hasMips32r3() const {
470 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
472 bool hasMips64r3() const {
473 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
475 bool hasMips32r5() const {
476 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
478 bool hasMips64r5() const {
479 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
481 bool hasMips32r6() const {
482 return STI.getFeatureBits()[Mips::FeatureMips32r6];
484 bool hasMips64r6() const {
485 return STI.getFeatureBits()[Mips::FeatureMips64r6];
488 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
489 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
490 bool hasDSPR3() const { return STI.getFeatureBits()[Mips::FeatureDSPR3]; }
491 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
492 bool hasCnMips() const {
493 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
500 bool inMips16Mode() const {
501 return STI.getFeatureBits()[Mips::FeatureMips16];
504 bool useTraps() const {
505 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
508 bool useSoftFloat() const {
509 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
512 /// Warn if RegIndex is the same as the current AT.
513 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
515 void warnIfNoMacro(SMLoc Loc);
517 bool isLittle() const { return IsLittleEndian; }
523 /// MipsOperand - Instances of this class represent a parsed Mips machine
525 class MipsOperand : public MCParsedAsmOperand {
527 /// Broad categories of register classes
528 /// The exact class is finalized by the render method.
530 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
531 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
533 RegKind_FCC = 4, /// FCC
534 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
535 RegKind_MSACtrl = 16, /// MSA control registers
536 RegKind_COP2 = 32, /// COP2
537 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
539 RegKind_CCR = 128, /// CCR
540 RegKind_HWRegs = 256, /// HWRegs
541 RegKind_COP3 = 512, /// COP3
542 RegKind_COP0 = 1024, /// COP0
543 /// Potentially any (e.g. $1)
544 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
545 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
546 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
551 k_Immediate, /// An immediate (possibly involving symbol references)
552 k_Memory, /// Base + Offset Memory Address
553 k_PhysRegister, /// A physical register from the Mips namespace
554 k_RegisterIndex, /// A register index in one or more RegKind.
555 k_Token, /// A simple token
556 k_RegList, /// A physical register list
557 k_RegPair /// A pair of physical register
561 MipsOperand(KindTy K, MipsAsmParser &Parser)
562 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
565 /// For diagnostics, and checking the assembler temporary
566 MipsAsmParser &AsmParser;
574 unsigned Num; /// Register Number
578 unsigned Index; /// Index into the register class
579 RegKind Kind; /// Bitfield of the kinds it could possibly be
580 const MCRegisterInfo *RegInfo;
593 SmallVector<unsigned, 10> *List;
598 struct PhysRegOp PhysReg;
599 struct RegIdxOp RegIdx;
602 struct RegListOp RegList;
605 SMLoc StartLoc, EndLoc;
607 /// Internal constructor for register kinds
608 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
609 const MCRegisterInfo *RegInfo,
611 MipsAsmParser &Parser) {
612 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
613 Op->RegIdx.Index = Index;
614 Op->RegIdx.RegInfo = RegInfo;
615 Op->RegIdx.Kind = RegKind;
622 /// Coerce the register to GPR32 and return the real register for the current
624 unsigned getGPR32Reg() const {
625 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
626 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
627 unsigned ClassID = Mips::GPR32RegClassID;
628 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
631 /// Coerce the register to GPR32 and return the real register for the current
633 unsigned getGPRMM16Reg() const {
634 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
635 unsigned ClassID = Mips::GPR32RegClassID;
636 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
639 /// Coerce the register to GPR64 and return the real register for the current
641 unsigned getGPR64Reg() const {
642 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
643 unsigned ClassID = Mips::GPR64RegClassID;
644 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
648 /// Coerce the register to AFGR64 and return the real register for the current
650 unsigned getAFGR64Reg() const {
651 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
652 if (RegIdx.Index % 2 != 0)
653 AsmParser.Warning(StartLoc, "Float register should be even.");
654 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
655 .getRegister(RegIdx.Index / 2);
658 /// Coerce the register to FGR64 and return the real register for the current
660 unsigned getFGR64Reg() const {
661 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
662 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
663 .getRegister(RegIdx.Index);
666 /// Coerce the register to FGR32 and return the real register for the current
668 unsigned getFGR32Reg() const {
669 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
670 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
671 .getRegister(RegIdx.Index);
674 /// Coerce the register to FGRH32 and return the real register for the current
676 unsigned getFGRH32Reg() const {
677 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
678 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
679 .getRegister(RegIdx.Index);
682 /// Coerce the register to FCC and return the real register for the current
684 unsigned getFCCReg() const {
685 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
686 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
687 .getRegister(RegIdx.Index);
690 /// Coerce the register to MSA128 and return the real register for the current
692 unsigned getMSA128Reg() const {
693 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
694 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
696 unsigned ClassID = Mips::MSA128BRegClassID;
697 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
700 /// Coerce the register to MSACtrl and return the real register for the
702 unsigned getMSACtrlReg() const {
703 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
704 unsigned ClassID = Mips::MSACtrlRegClassID;
705 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
708 /// Coerce the register to COP0 and return the real register for the
710 unsigned getCOP0Reg() const {
711 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
712 unsigned ClassID = Mips::COP0RegClassID;
713 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
716 /// Coerce the register to COP2 and return the real register for the
718 unsigned getCOP2Reg() const {
719 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
720 unsigned ClassID = Mips::COP2RegClassID;
721 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
724 /// Coerce the register to COP3 and return the real register for the
726 unsigned getCOP3Reg() const {
727 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
728 unsigned ClassID = Mips::COP3RegClassID;
729 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
732 /// Coerce the register to ACC64DSP and return the real register for the
734 unsigned getACC64DSPReg() const {
735 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
736 unsigned ClassID = Mips::ACC64DSPRegClassID;
737 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
740 /// Coerce the register to HI32DSP and return the real register for the
742 unsigned getHI32DSPReg() const {
743 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
744 unsigned ClassID = Mips::HI32DSPRegClassID;
745 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
748 /// Coerce the register to LO32DSP and return the real register for the
750 unsigned getLO32DSPReg() const {
751 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
752 unsigned ClassID = Mips::LO32DSPRegClassID;
753 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
756 /// Coerce the register to CCR and return the real register for the
758 unsigned getCCRReg() const {
759 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
760 unsigned ClassID = Mips::CCRRegClassID;
761 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
764 /// Coerce the register to HWRegs and return the real register for the
766 unsigned getHWRegsReg() const {
767 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
768 unsigned ClassID = Mips::HWRegsRegClassID;
769 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
773 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
774 // Add as immediate when possible. Null MCExpr = 0.
776 Inst.addOperand(MCOperand::createImm(0));
777 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
778 Inst.addOperand(MCOperand::createImm(CE->getValue()));
780 Inst.addOperand(MCOperand::createExpr(Expr));
783 void addRegOperands(MCInst &Inst, unsigned N) const {
784 llvm_unreachable("Use a custom parser instead");
787 /// Render the operand to an MCInst as a GPR32
788 /// Asserts if the wrong number of operands are requested, or the operand
789 /// is not a k_RegisterIndex compatible with RegKind_GPR
790 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
791 assert(N == 1 && "Invalid number of operands!");
792 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
795 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
796 assert(N == 1 && "Invalid number of operands!");
797 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
800 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
801 assert(N == 1 && "Invalid number of operands!");
802 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
805 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
806 assert(N == 1 && "Invalid number of operands!");
807 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
810 /// Render the operand to an MCInst as a GPR64
811 /// Asserts if the wrong number of operands are requested, or the operand
812 /// is not a k_RegisterIndex compatible with RegKind_GPR
813 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 1 && "Invalid number of operands!");
815 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
818 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
819 assert(N == 1 && "Invalid number of operands!");
820 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
823 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
824 assert(N == 1 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
828 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
829 assert(N == 1 && "Invalid number of operands!");
830 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
831 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
832 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
833 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
837 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
838 assert(N == 1 && "Invalid number of operands!");
839 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
842 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
843 assert(N == 1 && "Invalid number of operands!");
844 Inst.addOperand(MCOperand::createReg(getFCCReg()));
847 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 1 && "Invalid number of operands!");
849 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
852 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
853 assert(N == 1 && "Invalid number of operands!");
854 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
857 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
858 assert(N == 1 && "Invalid number of operands!");
859 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
862 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
863 assert(N == 1 && "Invalid number of operands!");
864 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
867 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
868 assert(N == 1 && "Invalid number of operands!");
869 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
872 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
873 assert(N == 1 && "Invalid number of operands!");
874 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
877 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
878 assert(N == 1 && "Invalid number of operands!");
879 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
882 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
883 assert(N == 1 && "Invalid number of operands!");
884 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
887 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
888 assert(N == 1 && "Invalid number of operands!");
889 Inst.addOperand(MCOperand::createReg(getCCRReg()));
892 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
893 assert(N == 1 && "Invalid number of operands!");
894 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
897 void addImmOperands(MCInst &Inst, unsigned N) const {
898 assert(N == 1 && "Invalid number of operands!");
899 const MCExpr *Expr = getImm();
903 void addMemOperands(MCInst &Inst, unsigned N) const {
904 assert(N == 2 && "Invalid number of operands!");
906 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
907 ? getMemBase()->getGPR64Reg()
908 : getMemBase()->getGPR32Reg()));
910 const MCExpr *Expr = getMemOff();
914 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
915 assert(N == 2 && "Invalid number of operands!");
917 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
919 const MCExpr *Expr = getMemOff();
923 void addRegListOperands(MCInst &Inst, unsigned N) const {
924 assert(N == 1 && "Invalid number of operands!");
926 for (auto RegNo : getRegList())
927 Inst.addOperand(MCOperand::createReg(RegNo));
930 void addRegPairOperands(MCInst &Inst, unsigned N) const {
931 assert(N == 2 && "Invalid number of operands!");
932 unsigned RegNo = getRegPair();
933 Inst.addOperand(MCOperand::createReg(RegNo++));
934 Inst.addOperand(MCOperand::createReg(RegNo));
937 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
938 assert(N == 2 && "Invalid number of operands!");
939 for (auto RegNo : getRegList())
940 Inst.addOperand(MCOperand::createReg(RegNo));
943 bool isReg() const override {
944 // As a special case until we sort out the definition of div/divu, pretend
945 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
946 if (isGPRAsmReg() && RegIdx.Index == 0)
949 return Kind == k_PhysRegister;
951 bool isRegIdx() const { return Kind == k_RegisterIndex; }
952 bool isImm() const override { return Kind == k_Immediate; }
953 bool isConstantImm() const {
954 return isImm() && dyn_cast<MCConstantExpr>(getImm());
956 template <unsigned Bits> bool isUImm() const {
957 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
959 bool isToken() const override {
960 // Note: It's not possible to pretend that other operand kinds are tokens.
961 // The matcher emitter checks tokens first.
962 return Kind == k_Token;
964 bool isMem() const override { return Kind == k_Memory; }
965 bool isConstantMemOff() const {
966 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
968 template <unsigned Bits> bool isMemWithSimmOffset() const {
969 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
970 && getMemBase()->isGPRAsmReg();
972 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
973 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
974 getMemBase()->isGPRAsmReg();
976 bool isMemWithGRPMM16Base() const {
977 return isMem() && getMemBase()->isMM16AsmReg();
979 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
980 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
981 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
983 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
984 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
985 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
986 && (getMemBase()->getGPR32Reg() == Mips::SP);
988 bool isUImm5Lsl2() const {
989 return (isImm() && isConstantImm() && isShiftedUInt<5, 2>(getConstantImm()));
991 bool isRegList16() const {
995 int Size = RegList.List->size();
996 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
997 RegList.List->back() != Mips::RA)
1000 int PrevReg = *RegList.List->begin();
1001 for (int i = 1; i < Size - 1; i++) {
1002 int Reg = (*(RegList.List))[i];
1003 if ( Reg != PrevReg + 1)
1010 bool isInvNum() const { return Kind == k_Immediate; }
1011 bool isLSAImm() const {
1012 if (!isConstantImm())
1014 int64_t Val = getConstantImm();
1015 return 1 <= Val && Val <= 4;
1017 bool isRegList() const { return Kind == k_RegList; }
1018 bool isMovePRegPair() const {
1019 if (Kind != k_RegList || RegList.List->size() != 2)
1022 unsigned R0 = RegList.List->front();
1023 unsigned R1 = RegList.List->back();
1025 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1026 (R0 == Mips::A1 && R1 == Mips::A3) ||
1027 (R0 == Mips::A2 && R1 == Mips::A3) ||
1028 (R0 == Mips::A0 && R1 == Mips::S5) ||
1029 (R0 == Mips::A0 && R1 == Mips::S6) ||
1030 (R0 == Mips::A0 && R1 == Mips::A1) ||
1031 (R0 == Mips::A0 && R1 == Mips::A2) ||
1032 (R0 == Mips::A0 && R1 == Mips::A3))
1038 StringRef getToken() const {
1039 assert(Kind == k_Token && "Invalid access!");
1040 return StringRef(Tok.Data, Tok.Length);
1042 bool isRegPair() const { return Kind == k_RegPair; }
1044 unsigned getReg() const override {
1045 // As a special case until we sort out the definition of div/divu, pretend
1046 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1047 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1048 RegIdx.Kind & RegKind_GPR)
1049 return getGPR32Reg(); // FIXME: GPR64 too
1051 assert(Kind == k_PhysRegister && "Invalid access!");
1055 const MCExpr *getImm() const {
1056 assert((Kind == k_Immediate) && "Invalid access!");
1060 int64_t getConstantImm() const {
1061 const MCExpr *Val = getImm();
1062 return static_cast<const MCConstantExpr *>(Val)->getValue();
1065 MipsOperand *getMemBase() const {
1066 assert((Kind == k_Memory) && "Invalid access!");
1070 const MCExpr *getMemOff() const {
1071 assert((Kind == k_Memory) && "Invalid access!");
1075 int64_t getConstantMemOff() const {
1076 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1079 const SmallVectorImpl<unsigned> &getRegList() const {
1080 assert((Kind == k_RegList) && "Invalid access!");
1081 return *(RegList.List);
1084 unsigned getRegPair() const {
1085 assert((Kind == k_RegPair) && "Invalid access!");
1086 return RegIdx.Index;
1089 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1090 MipsAsmParser &Parser) {
1091 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1092 Op->Tok.Data = Str.data();
1093 Op->Tok.Length = Str.size();
1099 /// Create a numeric register (e.g. $1). The exact register remains
1100 /// unresolved until an instruction successfully matches
1101 static std::unique_ptr<MipsOperand>
1102 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1103 SMLoc E, MipsAsmParser &Parser) {
1104 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1105 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1108 /// Create a register that is definitely a GPR.
1109 /// This is typically only used for named registers such as $gp.
1110 static std::unique_ptr<MipsOperand>
1111 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1112 MipsAsmParser &Parser) {
1113 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1116 /// Create a register that is definitely a FGR.
1117 /// This is typically only used for named registers such as $f0.
1118 static std::unique_ptr<MipsOperand>
1119 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1120 MipsAsmParser &Parser) {
1121 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1124 /// Create a register that is definitely a HWReg.
1125 /// This is typically only used for named registers such as $hwr_cpunum.
1126 static std::unique_ptr<MipsOperand>
1127 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1128 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1129 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1132 /// Create a register that is definitely an FCC.
1133 /// This is typically only used for named registers such as $fcc0.
1134 static std::unique_ptr<MipsOperand>
1135 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1136 MipsAsmParser &Parser) {
1137 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1140 /// Create a register that is definitely an ACC.
1141 /// This is typically only used for named registers such as $ac0.
1142 static std::unique_ptr<MipsOperand>
1143 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1144 MipsAsmParser &Parser) {
1145 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1148 /// Create a register that is definitely an MSA128.
1149 /// This is typically only used for named registers such as $w0.
1150 static std::unique_ptr<MipsOperand>
1151 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1152 SMLoc E, MipsAsmParser &Parser) {
1153 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1156 /// Create a register that is definitely an MSACtrl.
1157 /// This is typically only used for named registers such as $msaaccess.
1158 static std::unique_ptr<MipsOperand>
1159 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1160 SMLoc E, MipsAsmParser &Parser) {
1161 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1164 static std::unique_ptr<MipsOperand>
1165 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1166 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1173 static std::unique_ptr<MipsOperand>
1174 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1175 SMLoc E, MipsAsmParser &Parser) {
1176 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1177 Op->Mem.Base = Base.release();
1184 static std::unique_ptr<MipsOperand>
1185 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1186 MipsAsmParser &Parser) {
1187 assert (Regs.size() > 0 && "Empty list not allowed");
1189 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1190 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1191 Op->StartLoc = StartLoc;
1192 Op->EndLoc = EndLoc;
1196 static std::unique_ptr<MipsOperand>
1197 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1198 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1199 Op->RegIdx.Index = RegNo;
1205 bool isGPRAsmReg() const {
1206 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1208 bool isMM16AsmReg() const {
1209 if (!(isRegIdx() && RegIdx.Kind))
1211 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1212 || RegIdx.Index == 16 || RegIdx.Index == 17);
1214 bool isMM16AsmRegZero() const {
1215 if (!(isRegIdx() && RegIdx.Kind))
1217 return (RegIdx.Index == 0 ||
1218 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1219 RegIdx.Index == 17);
1221 bool isMM16AsmRegMoveP() const {
1222 if (!(isRegIdx() && RegIdx.Kind))
1224 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1225 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1227 bool isFGRAsmReg() const {
1228 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1229 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1231 bool isHWRegsAsmReg() const {
1232 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1234 bool isCCRAsmReg() const {
1235 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1237 bool isFCCAsmReg() const {
1238 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1240 if (!AsmParser.hasEightFccRegisters())
1241 return RegIdx.Index == 0;
1242 return RegIdx.Index <= 7;
1244 bool isACCAsmReg() const {
1245 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1247 bool isCOP0AsmReg() const {
1248 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1250 bool isCOP2AsmReg() const {
1251 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1253 bool isCOP3AsmReg() const {
1254 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1256 bool isMSA128AsmReg() const {
1257 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1259 bool isMSACtrlAsmReg() const {
1260 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1263 /// getStartLoc - Get the location of the first token of this operand.
1264 SMLoc getStartLoc() const override { return StartLoc; }
1265 /// getEndLoc - Get the location of the last token of this operand.
1266 SMLoc getEndLoc() const override { return EndLoc; }
1268 virtual ~MipsOperand() {
1276 delete RegList.List;
1277 case k_PhysRegister:
1278 case k_RegisterIndex:
1285 void print(raw_ostream &OS) const override {
1294 Mem.Base->print(OS);
1299 case k_PhysRegister:
1300 OS << "PhysReg<" << PhysReg.Num << ">";
1302 case k_RegisterIndex:
1303 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1310 for (auto Reg : (*RegList.List))
1315 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1319 }; // class MipsOperand
1323 extern const MCInstrDesc MipsInsts[];
1325 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1326 return MipsInsts[Opcode];
1329 static bool hasShortDelaySlot(unsigned Opcode) {
1332 case Mips::JALRS_MM:
1333 case Mips::JALRS16_MM:
1334 case Mips::BGEZALS_MM:
1335 case Mips::BLTZALS_MM:
1342 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1343 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1344 return &SRExpr->getSymbol();
1347 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1348 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1349 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1360 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1361 return getSingleMCSymbol(UExpr->getSubExpr());
1366 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1367 if (isa<MCSymbolRefExpr>(Expr))
1370 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1371 return countMCSymbolRefExpr(BExpr->getLHS()) +
1372 countMCSymbolRefExpr(BExpr->getRHS());
1374 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1375 return countMCSymbolRefExpr(UExpr->getSubExpr());
1381 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1382 SmallVectorImpl<MCInst> &Instructions) {
1384 tmpInst.setOpcode(Opcode);
1385 tmpInst.addOperand(MCOperand::createReg(Reg0));
1386 tmpInst.addOperand(Op1);
1387 tmpInst.setLoc(IDLoc);
1388 Instructions.push_back(tmpInst);
1391 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1392 SmallVectorImpl<MCInst> &Instructions) {
1393 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1396 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1397 SmallVectorImpl<MCInst> &Instructions) {
1398 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1401 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1402 SmallVectorImpl<MCInst> &Instructions) {
1404 tmpInst.setOpcode(Opcode);
1405 tmpInst.addOperand(MCOperand::createImm(Imm1));
1406 tmpInst.addOperand(MCOperand::createImm(Imm2));
1407 tmpInst.setLoc(IDLoc);
1408 Instructions.push_back(tmpInst);
1411 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1412 SmallVectorImpl<MCInst> &Instructions) {
1414 tmpInst.setOpcode(Opcode);
1415 tmpInst.addOperand(MCOperand::createReg(Reg0));
1416 tmpInst.setLoc(IDLoc);
1417 Instructions.push_back(tmpInst);
1420 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1421 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1423 tmpInst.setOpcode(Opcode);
1424 tmpInst.addOperand(MCOperand::createReg(Reg0));
1425 tmpInst.addOperand(MCOperand::createReg(Reg1));
1426 tmpInst.addOperand(Op2);
1427 tmpInst.setLoc(IDLoc);
1428 Instructions.push_back(tmpInst);
1431 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1432 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1433 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1437 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1438 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1439 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1443 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1444 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1445 if (ShiftAmount >= 32) {
1446 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1451 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1453 } // end anonymous namespace.
1455 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1456 SmallVectorImpl<MCInst> &Instructions) {
1457 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1458 bool ExpandedJalSym = false;
1462 if (MCID.isBranch() || MCID.isCall()) {
1463 const unsigned Opcode = Inst.getOpcode();
1473 assert(hasCnMips() && "instruction only valid for octeon cpus");
1480 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1481 Offset = Inst.getOperand(2);
1482 if (!Offset.isImm())
1483 break; // We'll deal with this situation later on when applying fixups.
1484 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1485 return Error(IDLoc, "branch target out of range");
1486 if (OffsetToAlignment(Offset.getImm(),
1487 1LL << (inMicroMipsMode() ? 1 : 2)))
1488 return Error(IDLoc, "branch to misaligned address");
1502 case Mips::BGEZAL_MM:
1503 case Mips::BLTZAL_MM:
1506 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1507 Offset = Inst.getOperand(1);
1508 if (!Offset.isImm())
1509 break; // We'll deal with this situation later on when applying fixups.
1510 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1511 return Error(IDLoc, "branch target out of range");
1512 if (OffsetToAlignment(Offset.getImm(),
1513 1LL << (inMicroMipsMode() ? 1 : 2)))
1514 return Error(IDLoc, "branch to misaligned address");
1516 case Mips::BEQZ16_MM:
1517 case Mips::BEQZC16_MMR6:
1518 case Mips::BNEZ16_MM:
1519 case Mips::BNEZC16_MMR6:
1520 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1521 Offset = Inst.getOperand(1);
1522 if (!Offset.isImm())
1523 break; // We'll deal with this situation later on when applying fixups.
1524 if (!isInt<8>(Offset.getImm()))
1525 return Error(IDLoc, "branch target out of range");
1526 if (OffsetToAlignment(Offset.getImm(), 2LL))
1527 return Error(IDLoc, "branch to misaligned address");
1532 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1533 // We still accept it but it is a normal nop.
1534 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1535 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1536 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1541 const unsigned Opcode = Inst.getOpcode();
1553 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1554 // The offset is handled above
1555 Opnd = Inst.getOperand(1);
1557 return Error(IDLoc, "expected immediate operand kind");
1558 Imm = Opnd.getImm();
1559 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1560 Opcode == Mips::BBIT1 ? 63 : 31))
1561 return Error(IDLoc, "immediate operand value out of range");
1563 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1565 Inst.getOperand(1).setImm(Imm - 32);
1573 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1575 Opnd = Inst.getOperand(3);
1577 return Error(IDLoc, "expected immediate operand kind");
1578 Imm = Opnd.getImm();
1579 if (Imm < 0 || Imm > 31)
1580 return Error(IDLoc, "immediate operand value out of range");
1582 Opnd = Inst.getOperand(2);
1584 return Error(IDLoc, "expected immediate operand kind");
1585 Imm = Opnd.getImm();
1586 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1587 Opcode == Mips::EXTS ? 63 : 31))
1588 return Error(IDLoc, "immediate operand value out of range");
1590 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1591 Inst.getOperand(2).setImm(Imm - 32);
1597 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1598 Opnd = Inst.getOperand(2);
1600 return Error(IDLoc, "expected immediate operand kind");
1601 Imm = Opnd.getImm();
1602 if (!isInt<10>(Imm))
1603 return Error(IDLoc, "immediate operand value out of range");
1608 // This expansion is not in a function called by tryExpandInstruction()
1609 // because the pseudo-instruction doesn't have a distinct opcode.
1610 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1612 warnIfNoMacro(IDLoc);
1614 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1616 // We can do this expansion if there's only 1 symbol in the argument
1618 if (countMCSymbolRefExpr(JalExpr) > 1)
1619 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1621 // FIXME: This is checking the expression can be handled by the later stages
1622 // of the assembler. We ought to leave it to those later stages but
1623 // we can't do that until we stop evaluateRelocExpr() rewriting the
1624 // expressions into non-equivalent forms.
1625 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1627 // FIXME: Add support for label+offset operands (currently causes an error).
1628 // FIXME: Add support for forward-declared local symbols.
1629 // FIXME: Add expansion for when the LargeGOT option is enabled.
1630 if (JalSym->isInSection() || JalSym->isTemporary()) {
1632 // If it's a local symbol and the O32 ABI is being used, we expand to:
1634 // R_(MICRO)MIPS_GOT16 label
1635 // addiu $25, $25, 0
1636 // R_(MICRO)MIPS_LO16 label
1638 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1639 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1641 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1642 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1643 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1644 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1645 } else if (isABI_N32() || isABI_N64()) {
1646 // If it's a local symbol and the N32/N64 ABIs are being used,
1648 // lw/ld $25, 0($gp)
1649 // R_(MICRO)MIPS_GOT_DISP label
1651 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1653 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1654 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1657 // If it's an external/weak symbol, we expand to:
1658 // lw/ld $25, 0($gp)
1659 // R_(MICRO)MIPS_CALL16 label
1661 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1663 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1664 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1668 if (IsCpRestoreSet && inMicroMipsMode())
1669 JalrInst.setOpcode(Mips::JALRS_MM);
1671 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1672 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1673 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1675 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1676 // This relocation is supposed to be an optimization hint for the linker
1677 // and is not necessary for correctness.
1680 ExpandedJalSym = true;
1683 if (MCID.mayLoad() || MCID.mayStore()) {
1684 // Check the offset of memory operand, if it is a symbol
1685 // reference or immediate we may have to expand instructions.
1686 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1687 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1688 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1689 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1690 MCOperand &Op = Inst.getOperand(i);
1692 int MemOffset = Op.getImm();
1693 if (MemOffset < -32768 || MemOffset > 32767) {
1694 // Offset can't exceed 16bit value.
1695 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1698 } else if (Op.isExpr()) {
1699 const MCExpr *Expr = Op.getExpr();
1700 if (Expr->getKind() == MCExpr::SymbolRef) {
1701 const MCSymbolRefExpr *SR =
1702 static_cast<const MCSymbolRefExpr *>(Expr);
1703 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1705 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1708 } else if (!isEvaluated(Expr)) {
1709 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1717 if (inMicroMipsMode()) {
1718 if (MCID.mayLoad()) {
1719 // Try to create 16-bit GP relative load instruction.
1720 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1721 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1722 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1723 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1724 MCOperand &Op = Inst.getOperand(i);
1726 int MemOffset = Op.getImm();
1727 MCOperand &DstReg = Inst.getOperand(0);
1728 MCOperand &BaseReg = Inst.getOperand(1);
1729 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1730 getContext().getRegisterInfo()->getRegClass(
1731 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1732 (BaseReg.getReg() == Mips::GP ||
1733 BaseReg.getReg() == Mips::GP_64)) {
1735 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1736 IDLoc, Instructions);
1744 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1749 switch (Inst.getOpcode()) {
1752 case Mips::ADDIUS5_MM:
1753 Opnd = Inst.getOperand(2);
1755 return Error(IDLoc, "expected immediate operand kind");
1756 Imm = Opnd.getImm();
1757 if (Imm < -8 || Imm > 7)
1758 return Error(IDLoc, "immediate operand value out of range");
1760 case Mips::ADDIUSP_MM:
1761 Opnd = Inst.getOperand(0);
1763 return Error(IDLoc, "expected immediate operand kind");
1764 Imm = Opnd.getImm();
1765 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1767 return Error(IDLoc, "immediate operand value out of range");
1769 case Mips::SLL16_MM:
1770 case Mips::SRL16_MM:
1771 Opnd = Inst.getOperand(2);
1773 return Error(IDLoc, "expected immediate operand kind");
1774 Imm = Opnd.getImm();
1775 if (Imm < 1 || Imm > 8)
1776 return Error(IDLoc, "immediate operand value out of range");
1779 Opnd = Inst.getOperand(1);
1781 return Error(IDLoc, "expected immediate operand kind");
1782 Imm = Opnd.getImm();
1783 if (Imm < -1 || Imm > 126)
1784 return Error(IDLoc, "immediate operand value out of range");
1786 case Mips::ADDIUR2_MM:
1787 Opnd = Inst.getOperand(2);
1789 return Error(IDLoc, "expected immediate operand kind");
1790 Imm = Opnd.getImm();
1791 if (!(Imm == 1 || Imm == -1 ||
1792 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1793 return Error(IDLoc, "immediate operand value out of range");
1795 case Mips::ADDIUR1SP_MM:
1796 Opnd = Inst.getOperand(1);
1798 return Error(IDLoc, "expected immediate operand kind");
1799 Imm = Opnd.getImm();
1800 if (OffsetToAlignment(Imm, 4LL))
1801 return Error(IDLoc, "misaligned immediate operand value");
1802 if (Imm < 0 || Imm > 255)
1803 return Error(IDLoc, "immediate operand value out of range");
1805 case Mips::ANDI16_MM:
1806 Opnd = Inst.getOperand(2);
1808 return Error(IDLoc, "expected immediate operand kind");
1809 Imm = Opnd.getImm();
1810 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1811 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1812 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1813 return Error(IDLoc, "immediate operand value out of range");
1815 case Mips::LBU16_MM:
1816 Opnd = Inst.getOperand(2);
1818 return Error(IDLoc, "expected immediate operand kind");
1819 Imm = Opnd.getImm();
1820 if (Imm < -1 || Imm > 14)
1821 return Error(IDLoc, "immediate operand value out of range");
1830 Opnd = Inst.getOperand(2);
1832 return Error(IDLoc, "expected immediate operand kind");
1833 Imm = Opnd.getImm();
1834 if (Imm < 0 || Imm > 15)
1835 return Error(IDLoc, "immediate operand value out of range");
1837 case Mips::LHU16_MM:
1839 Opnd = Inst.getOperand(2);
1841 return Error(IDLoc, "expected immediate operand kind");
1842 Imm = Opnd.getImm();
1843 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1844 return Error(IDLoc, "immediate operand value out of range");
1848 Opnd = Inst.getOperand(2);
1850 return Error(IDLoc, "expected immediate operand kind");
1851 Imm = Opnd.getImm();
1852 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1853 return Error(IDLoc, "immediate operand value out of range");
1855 case Mips::PREFX_MM:
1858 Opnd = Inst.getOperand(2);
1860 return Error(IDLoc, "expected immediate operand kind");
1861 Imm = Opnd.getImm();
1862 if (!isUInt<5>(Imm))
1863 return Error(IDLoc, "immediate operand value out of range");
1865 case Mips::ADDIUPC_MM:
1866 MCOperand Opnd = Inst.getOperand(1);
1868 return Error(IDLoc, "expected immediate operand kind");
1869 int Imm = Opnd.getImm();
1870 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1871 return Error(IDLoc, "immediate operand value out of range");
1876 MacroExpanderResultTy ExpandResult =
1877 tryExpandInstruction(Inst, IDLoc, Instructions);
1878 switch (ExpandResult) {
1880 Instructions.push_back(Inst);
1888 // If this instruction has a delay slot and .set reorder is active,
1889 // emit a NOP after it.
1890 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1891 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1893 if ((Inst.getOpcode() == Mips::JalOneReg ||
1894 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1895 isPicAndNotNxxAbi()) {
1896 if (IsCpRestoreSet) {
1897 // We need a NOP between the JALR and the LW:
1898 // If .set reorder has been used, we've already emitted a NOP.
1899 // If .set noreorder has been used, we need to emit a NOP at this point.
1900 if (!AssemblerOptions.back()->isReorder())
1901 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1903 // Load the $gp from the stack.
1904 SmallVector<MCInst, 3> LoadInsts;
1905 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1908 for (const MCInst &Inst : LoadInsts)
1909 Instructions.push_back(Inst);
1912 Warning(IDLoc, "no .cprestore used in PIC mode");
1918 MipsAsmParser::MacroExpanderResultTy
1919 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
1920 SmallVectorImpl<MCInst> &Instructions) {
1921 switch (Inst.getOpcode()) {
1923 return MER_NotAMacro;
1924 case Mips::LoadImm32:
1925 return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
1927 case Mips::LoadImm64:
1928 return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
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(Inst.getOperand(0).getReg(), Mips::NoRegister,
1938 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1942 case Mips::LoadAddrReg32:
1943 case Mips::LoadAddrReg64:
1944 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1945 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1946 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1947 "expected immediate operand kind");
1949 return expandLoadAddress(Inst.getOperand(0).getReg(),
1950 Inst.getOperand(1).getReg(), Inst.getOperand(2),
1951 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
1955 case Mips::B_MM_Pseudo:
1956 case Mips::B_MMR6_Pseudo:
1957 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
1961 return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
1963 case Mips::JalOneReg:
1964 case Mips::JalTwoReg:
1965 return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
1969 return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
1986 case Mips::BLTImmMacro:
1987 case Mips::BLEImmMacro:
1988 case Mips::BGEImmMacro:
1989 case Mips::BGTImmMacro:
1990 case Mips::BLTUImmMacro:
1991 case Mips::BLEUImmMacro:
1992 case Mips::BGEUImmMacro:
1993 case Mips::BGTUImmMacro:
1994 case Mips::BLTLImmMacro:
1995 case Mips::BLELImmMacro:
1996 case Mips::BGELImmMacro:
1997 case Mips::BGTLImmMacro:
1998 case Mips::BLTULImmMacro:
1999 case Mips::BLEULImmMacro:
2000 case Mips::BGEULImmMacro:
2001 case Mips::BGTULImmMacro:
2002 return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2004 case Mips::SDivMacro:
2005 return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2007 case Mips::DSDivMacro:
2008 return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2010 case Mips::UDivMacro:
2011 return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2013 case Mips::DUDivMacro:
2014 return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2017 return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2019 return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2021 return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2023 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2029 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2030 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2031 int64_t ImmValue = Inst.getOperand(2).getImm();
2032 if (isInt<16>(ImmValue))
2033 return MER_NotAMacro;
2034 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2037 return MER_NotAMacro;
2041 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2042 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2043 int64_t ImmValue = Inst.getOperand(2).getImm();
2044 if (isUInt<16>(ImmValue))
2045 return MER_NotAMacro;
2046 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2049 return MER_NotAMacro;
2053 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2054 SmallVectorImpl<MCInst> &Instructions) {
2055 // Create a JALR instruction which is going to replace the pseudo-JAL.
2057 JalrInst.setLoc(IDLoc);
2058 const MCOperand FirstRegOp = Inst.getOperand(0);
2059 const unsigned Opcode = Inst.getOpcode();
2061 if (Opcode == Mips::JalOneReg) {
2062 // jal $rs => jalr $rs
2063 if (IsCpRestoreSet && inMicroMipsMode()) {
2064 JalrInst.setOpcode(Mips::JALRS16_MM);
2065 JalrInst.addOperand(FirstRegOp);
2066 } else if (inMicroMipsMode()) {
2067 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2068 JalrInst.addOperand(FirstRegOp);
2070 JalrInst.setOpcode(Mips::JALR);
2071 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2072 JalrInst.addOperand(FirstRegOp);
2074 } else if (Opcode == Mips::JalTwoReg) {
2075 // jal $rd, $rs => jalr $rd, $rs
2076 if (IsCpRestoreSet && inMicroMipsMode())
2077 JalrInst.setOpcode(Mips::JALRS_MM);
2079 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2080 JalrInst.addOperand(FirstRegOp);
2081 const MCOperand SecondRegOp = Inst.getOperand(1);
2082 JalrInst.addOperand(SecondRegOp);
2084 Instructions.push_back(JalrInst);
2086 // If .set reorder is active and branch instruction has a delay slot,
2087 // emit a NOP after it.
2088 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2089 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2090 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2096 /// Can the value be represented by a unsigned N-bit value and a shift left?
2097 template<unsigned N>
2098 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2099 unsigned BitNum = findFirstSet(x);
2101 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2104 /// Load (or add) an immediate into a register.
2106 /// @param ImmValue The immediate to load.
2107 /// @param DstReg The register that will hold the immediate.
2108 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2109 /// for a simple initialization.
2110 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2111 /// @param IsAddress True if the immediate represents an address. False if it
2113 /// @param IDLoc Location of the immediate in the source file.
2114 /// @param Instructions The instructions emitted by this expansion.
2115 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2116 unsigned SrcReg, bool Is32BitImm,
2117 bool IsAddress, SMLoc IDLoc,
2118 SmallVectorImpl<MCInst> &Instructions) {
2119 if (!Is32BitImm && !isGP64bit()) {
2120 Error(IDLoc, "instruction requires a 64-bit architecture");
2125 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2126 // Sign extend up to 64-bit so that the predicates match the hardware
2127 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2129 ImmValue = SignExtend64<32>(ImmValue);
2131 Error(IDLoc, "instruction requires a 32-bit immediate");
2136 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2137 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2139 bool UseSrcReg = false;
2140 if (SrcReg != Mips::NoRegister)
2143 unsigned TmpReg = DstReg;
2144 if (UseSrcReg && (DstReg == SrcReg)) {
2145 // At this point we need AT to perform the expansions and we exit if it is
2147 unsigned ATReg = getATReg(IDLoc);
2153 if (isInt<16>(ImmValue)) {
2157 // This doesn't quite follow the usual ABI expectations for N32 but matches
2158 // traditional assembler behaviour. N32 would normally use addiu for both
2159 // integers and addresses.
2160 if (IsAddress && !Is32BitImm) {
2161 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2165 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2169 if (isUInt<16>(ImmValue)) {
2170 unsigned TmpReg = DstReg;
2171 if (SrcReg == DstReg) {
2172 TmpReg = getATReg(IDLoc);
2177 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2179 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2183 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2184 warnIfNoMacro(IDLoc);
2186 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2187 uint16_t Bits15To0 = ImmValue & 0xffff;
2189 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2190 // Traditional behaviour seems to special case this particular value. It's
2191 // not clear why other masks are handled differently.
2192 if (ImmValue == 0xffffffff) {
2193 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2194 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2196 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2200 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2202 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2203 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2205 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2207 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2211 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2213 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2215 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2219 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2221 Error(IDLoc, "instruction requires a 32-bit immediate");
2225 // Traditionally, these immediates are shifted as little as possible and as
2226 // such we align the most significant bit to bit 15 of our temporary.
2227 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2228 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2229 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2230 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2231 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2232 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2235 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2240 warnIfNoMacro(IDLoc);
2242 // The remaining case is packed with a sequence of dsll and ori with zeros
2243 // being omitted and any neighbouring dsll's being coalesced.
2244 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2246 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2247 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2248 IDLoc, Instructions))
2251 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2252 // skip it and defer the shift to the next chunk.
2253 unsigned ShiftCarriedForwards = 16;
2254 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2255 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2257 if (ImmChunk != 0) {
2258 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2260 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2261 ShiftCarriedForwards = 0;
2264 ShiftCarriedForwards += 16;
2266 ShiftCarriedForwards -= 16;
2268 // Finish any remaining shifts left by trailing zeros.
2269 if (ShiftCarriedForwards)
2270 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2274 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2279 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2280 SmallVectorImpl<MCInst> &Instructions) {
2281 const MCOperand &ImmOp = Inst.getOperand(1);
2282 assert(ImmOp.isImm() && "expected immediate operand kind");
2283 const MCOperand &DstRegOp = Inst.getOperand(0);
2284 assert(DstRegOp.isReg() && "expected register operand kind");
2286 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2287 Is32BitImm, false, IDLoc, Instructions))
2293 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2294 const MCOperand &Offset,
2295 bool Is32BitAddress, SMLoc IDLoc,
2296 SmallVectorImpl<MCInst> &Instructions) {
2297 // la can't produce a usable address when addresses are 64-bit.
2298 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2299 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2300 // We currently can't do this because we depend on the equality
2301 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2302 Error(IDLoc, "la used to load 64-bit address");
2303 // Continue as if we had 'dla' instead.
2304 Is32BitAddress = false;
2307 // dla requires 64-bit addresses.
2308 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2309 Error(IDLoc, "instruction requires a 64-bit architecture");
2313 if (!Offset.isImm())
2314 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2315 Is32BitAddress, IDLoc, Instructions);
2317 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2318 IDLoc, Instructions);
2321 bool MipsAsmParser::loadAndAddSymbolAddress(
2322 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2323 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2324 warnIfNoMacro(IDLoc);
2326 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2327 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2328 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2329 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2330 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2332 bool UseSrcReg = SrcReg != Mips::NoRegister;
2334 // This is the 64-bit symbol address expansion.
2335 if (ABI.ArePtrs64bit() && isGP64bit()) {
2336 // We always need AT for the 64-bit expansion.
2337 // If it is not available we exit.
2338 unsigned ATReg = getATReg(IDLoc);
2342 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2343 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2344 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2345 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2347 if (UseSrcReg && (DstReg == SrcReg)) {
2348 // If $rs is the same as $rd:
2349 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2350 // daddiu $at, $at, %higher(sym)
2351 // dsll $at, $at, 16
2352 // daddiu $at, $at, %hi(sym)
2353 // dsll $at, $at, 16
2354 // daddiu $at, $at, %lo(sym)
2355 // daddu $rd, $at, $rd
2356 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2358 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2359 IDLoc, Instructions);
2360 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2361 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2363 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2364 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2366 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2371 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2372 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2373 // lui $at, %hi(sym)
2374 // daddiu $rd, $rd, %higher(sym)
2375 // daddiu $at, $at, %lo(sym)
2376 // dsll32 $rd, $rd, 0
2377 // daddu $rd, $rd, $at
2378 // (daddu $rd, $rd, $rs)
2379 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2381 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2383 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2384 IDLoc, Instructions);
2385 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2387 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2388 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2390 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2395 // And now, the 32-bit symbol address expansion:
2396 // If $rs is the same as $rd:
2397 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2398 // ori $at, $at, %lo(sym)
2399 // addu $rd, $at, $rd
2400 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2401 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2402 // ori $rd, $rd, %lo(sym)
2403 // (addu $rd, $rd, $rs)
2404 unsigned TmpReg = DstReg;
2405 if (UseSrcReg && (DstReg == SrcReg)) {
2406 // If $rs is the same as $rd, we need to use AT.
2407 // If it is not available we exit.
2408 unsigned ATReg = getATReg(IDLoc);
2414 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2415 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2419 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2421 assert(DstReg == TmpReg);
2426 bool MipsAsmParser::expandUncondBranchMMPseudo(
2427 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2428 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2429 "unexpected number of operands");
2431 MCOperand Offset = Inst.getOperand(0);
2432 if (Offset.isExpr()) {
2434 Inst.setOpcode(Mips::BEQ_MM);
2435 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2436 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2437 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2439 assert(Offset.isImm() && "expected immediate operand kind");
2440 if (isInt<11>(Offset.getImm())) {
2441 // If offset fits into 11 bits then this instruction becomes microMIPS
2442 // 16-bit unconditional branch instruction.
2443 if (inMicroMipsMode())
2444 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2446 if (!isInt<17>(Offset.getImm()))
2447 Error(IDLoc, "branch target out of range");
2448 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2449 Error(IDLoc, "branch to misaligned address");
2451 Inst.setOpcode(Mips::BEQ_MM);
2452 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2453 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2454 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2457 Instructions.push_back(Inst);
2459 // If .set reorder is active and branch instruction has a delay slot,
2460 // emit a NOP after it.
2461 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2462 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2463 createNop(true, IDLoc, Instructions);
2468 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2469 SmallVectorImpl<MCInst> &Instructions) {
2470 const MCOperand &DstRegOp = Inst.getOperand(0);
2471 assert(DstRegOp.isReg() && "expected register operand kind");
2473 const MCOperand &ImmOp = Inst.getOperand(1);
2474 assert(ImmOp.isImm() && "expected immediate operand kind");
2476 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2477 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2479 unsigned OpCode = 0;
2480 switch(Inst.getOpcode()) {
2488 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2492 int64_t ImmValue = ImmOp.getImm();
2494 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2497 warnIfNoMacro(IDLoc);
2499 unsigned ATReg = getATReg(IDLoc);
2503 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2504 IDLoc, Instructions))
2507 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2512 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2513 SmallVectorImpl<MCInst> &Instructions,
2514 bool isLoad, bool isImmOpnd) {
2515 unsigned ImmOffset, HiOffset, LoOffset;
2516 const MCExpr *ExprOffset;
2518 // 1st operand is either the source or destination register.
2519 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2520 unsigned RegOpNum = Inst.getOperand(0).getReg();
2521 // 2nd operand is the base register.
2522 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2523 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2524 // 3rd operand is either an immediate or expression.
2526 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2527 ImmOffset = Inst.getOperand(2).getImm();
2528 LoOffset = ImmOffset & 0x0000ffff;
2529 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2530 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2531 if (LoOffset & 0x8000)
2534 ExprOffset = Inst.getOperand(2).getExpr();
2535 // These are some of the types of expansions we perform here:
2536 // 1) lw $8, sym => lui $8, %hi(sym)
2537 // lw $8, %lo(sym)($8)
2538 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2540 // lw $8, %lo(offset)($9)
2541 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2543 // lw $8, %lo(offset)($at)
2544 // 4) sw $8, sym => lui $at, %hi(sym)
2545 // sw $8, %lo(sym)($at)
2546 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2548 // sw $8, %lo(offset)($at)
2549 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2550 // ldc1 $f0, %lo(sym)($at)
2552 // For load instructions we can use the destination register as a temporary
2553 // if base and dst are different (examples 1 and 2) and if the base register
2554 // is general purpose otherwise we must use $at (example 6) and error if it's
2555 // not available. For stores we must use $at (examples 4 and 5) because we
2556 // must not clobber the source register setting up the offset.
2557 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2558 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2559 unsigned RegClassIDOp0 =
2560 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2561 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2562 (RegClassIDOp0 == Mips::GPR64RegClassID);
2563 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2564 TmpRegNum = RegOpNum;
2566 // At this point we need AT to perform the expansions and we exit if it is
2568 TmpRegNum = getATReg(IDLoc);
2573 emitRX(Mips::LUi, TmpRegNum,
2574 isImmOpnd ? MCOperand::createImm(HiOffset)
2575 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2576 IDLoc, Instructions);
2577 // Add temp register to base.
2578 if (BaseRegNum != Mips::ZERO)
2579 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2580 // And finally, create original instruction with low part
2581 // of offset and new base.
2582 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2584 ? MCOperand::createImm(LoOffset)
2585 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2586 IDLoc, Instructions);
2590 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2591 SmallVectorImpl<MCInst> &Instructions) {
2592 unsigned OpNum = Inst.getNumOperands();
2593 unsigned Opcode = Inst.getOpcode();
2594 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2596 assert (Inst.getOperand(OpNum - 1).isImm() &&
2597 Inst.getOperand(OpNum - 2).isReg() &&
2598 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2600 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2601 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2602 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2603 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2604 // It can be implemented as SWM16 or LWM16 instruction.
2605 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2607 Inst.setOpcode(NewOpcode);
2608 Instructions.push_back(Inst);
2612 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2613 SmallVectorImpl<MCInst> &Instructions) {
2614 bool EmittedNoMacroWarning = false;
2615 unsigned PseudoOpcode = Inst.getOpcode();
2616 unsigned SrcReg = Inst.getOperand(0).getReg();
2617 const MCOperand &TrgOp = Inst.getOperand(1);
2618 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2620 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2621 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2625 TrgReg = TrgOp.getReg();
2626 else if (TrgOp.isImm()) {
2627 warnIfNoMacro(IDLoc);
2628 EmittedNoMacroWarning = true;
2630 TrgReg = getATReg(IDLoc);
2634 switch(PseudoOpcode) {
2636 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2637 case Mips::BLTImmMacro:
2638 PseudoOpcode = Mips::BLT;
2640 case Mips::BLEImmMacro:
2641 PseudoOpcode = Mips::BLE;
2643 case Mips::BGEImmMacro:
2644 PseudoOpcode = Mips::BGE;
2646 case Mips::BGTImmMacro:
2647 PseudoOpcode = Mips::BGT;
2649 case Mips::BLTUImmMacro:
2650 PseudoOpcode = Mips::BLTU;
2652 case Mips::BLEUImmMacro:
2653 PseudoOpcode = Mips::BLEU;
2655 case Mips::BGEUImmMacro:
2656 PseudoOpcode = Mips::BGEU;
2658 case Mips::BGTUImmMacro:
2659 PseudoOpcode = Mips::BGTU;
2661 case Mips::BLTLImmMacro:
2662 PseudoOpcode = Mips::BLTL;
2664 case Mips::BLELImmMacro:
2665 PseudoOpcode = Mips::BLEL;
2667 case Mips::BGELImmMacro:
2668 PseudoOpcode = Mips::BGEL;
2670 case Mips::BGTLImmMacro:
2671 PseudoOpcode = Mips::BGTL;
2673 case Mips::BLTULImmMacro:
2674 PseudoOpcode = Mips::BLTUL;
2676 case Mips::BLEULImmMacro:
2677 PseudoOpcode = Mips::BLEUL;
2679 case Mips::BGEULImmMacro:
2680 PseudoOpcode = Mips::BGEUL;
2682 case Mips::BGTULImmMacro:
2683 PseudoOpcode = Mips::BGTUL;
2687 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2688 false, IDLoc, Instructions))
2692 switch (PseudoOpcode) {
2697 AcceptsEquality = false;
2698 ReverseOrderSLT = false;
2699 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2700 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2701 ZeroSrcOpcode = Mips::BGTZ;
2702 ZeroTrgOpcode = Mips::BLTZ;
2708 AcceptsEquality = true;
2709 ReverseOrderSLT = true;
2710 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2711 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2712 ZeroSrcOpcode = Mips::BGEZ;
2713 ZeroTrgOpcode = Mips::BLEZ;
2719 AcceptsEquality = true;
2720 ReverseOrderSLT = false;
2721 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2722 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2723 ZeroSrcOpcode = Mips::BLEZ;
2724 ZeroTrgOpcode = Mips::BGEZ;
2730 AcceptsEquality = false;
2731 ReverseOrderSLT = true;
2732 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2733 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2734 ZeroSrcOpcode = Mips::BLTZ;
2735 ZeroTrgOpcode = Mips::BGTZ;
2738 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2741 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2742 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2743 if (IsSrcRegZero && IsTrgRegZero) {
2744 // FIXME: All of these Opcode-specific if's are needed for compatibility
2745 // with GAS' behaviour. However, they may not generate the most efficient
2746 // code in some circumstances.
2747 if (PseudoOpcode == Mips::BLT) {
2748 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2752 if (PseudoOpcode == Mips::BLE) {
2753 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2755 Warning(IDLoc, "branch is always taken");
2758 if (PseudoOpcode == Mips::BGE) {
2759 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2761 Warning(IDLoc, "branch is always taken");
2764 if (PseudoOpcode == Mips::BGT) {
2765 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2769 if (PseudoOpcode == Mips::BGTU) {
2770 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2771 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2774 if (AcceptsEquality) {
2775 // If both registers are $0 and the pseudo-branch accepts equality, it
2776 // will always be taken, so we emit an unconditional branch.
2777 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2778 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2779 Warning(IDLoc, "branch is always taken");
2782 // If both registers are $0 and the pseudo-branch does not accept
2783 // equality, it will never be taken, so we don't have to emit anything.
2786 if (IsSrcRegZero || IsTrgRegZero) {
2787 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2788 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2789 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2790 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2791 // the pseudo-branch will never be taken, so we don't emit anything.
2792 // This only applies to unsigned pseudo-branches.
2795 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2796 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2797 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2798 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2799 // the pseudo-branch will always be taken, so we emit an unconditional
2801 // This only applies to unsigned pseudo-branches.
2802 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2803 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2804 Warning(IDLoc, "branch is always taken");
2808 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2809 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2810 // the pseudo-branch will be taken only when the non-zero register is
2811 // different from 0, so we emit a BNEZ.
2813 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2814 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2815 // the pseudo-branch will be taken only when the non-zero register is
2816 // equal to 0, so we emit a BEQZ.
2818 // Because only BLEU and BGEU branch on equality, we can use the
2819 // AcceptsEquality variable to decide when to emit the BEQZ.
2820 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2821 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2822 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2825 // If we have a signed pseudo-branch and one of the registers is $0,
2826 // we can use an appropriate compare-to-zero branch. We select which one
2827 // to use in the switch statement above.
2828 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2829 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2830 IDLoc, Instructions);
2834 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2835 // expansions. If it is not available, we return.
2836 unsigned ATRegNum = getATReg(IDLoc);
2840 if (!EmittedNoMacroWarning)
2841 warnIfNoMacro(IDLoc);
2843 // SLT fits well with 2 of our 4 pseudo-branches:
2844 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2845 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2846 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2847 // This is accomplished by using a BNEZ with the result of the SLT.
2849 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2850 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2851 // Because only BGE and BLE branch on equality, we can use the
2852 // AcceptsEquality variable to decide when to emit the BEQZ.
2853 // Note that the order of the SLT arguments doesn't change between
2856 // The same applies to the unsigned variants, except that SLTu is used
2858 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2859 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2860 IDLoc, Instructions);
2862 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2863 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2864 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2869 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2870 SmallVectorImpl<MCInst> &Instructions,
2871 const bool IsMips64, const bool Signed) {
2872 if (hasMips32r6()) {
2873 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2877 warnIfNoMacro(IDLoc);
2879 const MCOperand &RsRegOp = Inst.getOperand(0);
2880 assert(RsRegOp.isReg() && "expected register operand kind");
2881 unsigned RsReg = RsRegOp.getReg();
2883 const MCOperand &RtRegOp = Inst.getOperand(1);
2884 assert(RtRegOp.isReg() && "expected register operand kind");
2885 unsigned RtReg = RtRegOp.getReg();
2890 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2891 ZeroReg = Mips::ZERO_64;
2893 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2894 ZeroReg = Mips::ZERO;
2897 bool UseTraps = useTraps();
2899 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2900 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2901 Warning(IDLoc, "dividing zero by zero");
2903 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2905 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2909 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2913 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2918 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2919 Warning(IDLoc, "division by zero");
2922 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2926 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2931 // FIXME: The values for these two BranchTarget variables may be different in
2932 // micromips. These magic numbers need to be removed.
2933 unsigned BranchTargetNoTraps;
2934 unsigned BranchTarget;
2937 BranchTarget = IsMips64 ? 12 : 8;
2938 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2940 BranchTarget = IsMips64 ? 20 : 16;
2941 BranchTargetNoTraps = 8;
2942 // Branch to the li instruction.
2943 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2947 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2950 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2953 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2957 unsigned ATReg = getATReg(IDLoc);
2961 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2963 // Branch to the mflo instruction.
2964 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2965 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2966 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2968 // Branch to the mflo instruction.
2969 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2970 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2974 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2976 // Branch to the mflo instruction.
2977 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2978 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2979 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2981 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2985 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
2986 SmallVectorImpl<MCInst> &Instructions) {
2987 if (hasMips32r6() || hasMips64r6()) {
2988 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2992 warnIfNoMacro(IDLoc);
2994 const MCOperand &DstRegOp = Inst.getOperand(0);
2995 assert(DstRegOp.isReg() && "expected register operand kind");
2997 const MCOperand &SrcRegOp = Inst.getOperand(1);
2998 assert(SrcRegOp.isReg() && "expected register operand kind");
3000 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3001 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3003 unsigned DstReg = DstRegOp.getReg();
3004 unsigned SrcReg = SrcRegOp.getReg();
3005 int64_t OffsetValue = OffsetImmOp.getImm();
3007 // NOTE: We always need AT for ULHU, as it is always used as the source
3008 // register for one of the LBu's.
3009 unsigned ATReg = getATReg(IDLoc);
3013 // When the value of offset+1 does not fit in 16 bits, we have to load the
3014 // offset in AT, (D)ADDu the original source register (if there was one), and
3015 // then use AT as the source register for the 2 generated LBu's.
3016 bool LoadedOffsetInAT = false;
3017 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3018 LoadedOffsetInAT = true;
3020 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3021 true, IDLoc, Instructions))
3024 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3025 // because it will make our output more similar to GAS'. For example,
3026 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3027 // instead of just an "ori $1, $9, 32768".
3028 // NOTE: If there is no source register specified in the ULHU, the parser
3029 // will interpret it as $0.
3030 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3031 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3034 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3035 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3036 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3038 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3040 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3041 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3043 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3044 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3047 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3049 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3050 FirstLbuOffset, IDLoc, Instructions);
3052 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3055 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3057 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3062 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3063 SmallVectorImpl<MCInst> &Instructions) {
3064 if (hasMips32r6() || hasMips64r6()) {
3065 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3069 const MCOperand &DstRegOp = Inst.getOperand(0);
3070 assert(DstRegOp.isReg() && "expected register operand kind");
3072 const MCOperand &SrcRegOp = Inst.getOperand(1);
3073 assert(SrcRegOp.isReg() && "expected register operand kind");
3075 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3076 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3078 unsigned SrcReg = SrcRegOp.getReg();
3079 int64_t OffsetValue = OffsetImmOp.getImm();
3082 // When the value of offset+3 does not fit in 16 bits, we have to load the
3083 // offset in AT, (D)ADDu the original source register (if there was one), and
3084 // then use AT as the source register for the generated LWL and LWR.
3085 bool LoadedOffsetInAT = false;
3086 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3087 ATReg = getATReg(IDLoc);
3090 LoadedOffsetInAT = true;
3092 warnIfNoMacro(IDLoc);
3094 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3095 true, IDLoc, Instructions))
3098 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3099 // because it will make our output more similar to GAS'. For example,
3100 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3101 // instead of just an "ori $1, $9, 32768".
3102 // NOTE: If there is no source register specified in the ULW, the parser
3103 // will interpret it as $0.
3104 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3105 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3108 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3109 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3111 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3112 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3114 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3115 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3118 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3121 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3127 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3128 SmallVectorImpl<MCInst> &Instructions) {
3130 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3131 assert (Inst.getOperand(0).isReg() &&
3132 Inst.getOperand(1).isReg() &&
3133 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3135 unsigned ATReg = Mips::NoRegister;
3136 unsigned FinalDstReg = Mips::NoRegister;
3137 unsigned DstReg = Inst.getOperand(0).getReg();
3138 unsigned SrcReg = Inst.getOperand(1).getReg();
3139 int64_t ImmValue = Inst.getOperand(2).getImm();
3141 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3143 unsigned FinalOpcode = Inst.getOpcode();
3145 if (DstReg == SrcReg) {
3146 ATReg = getATReg(Inst.getLoc());
3149 FinalDstReg = DstReg;
3153 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3154 switch (FinalOpcode) {
3156 llvm_unreachable("unimplemented expansion");
3158 FinalOpcode = Mips::ADD;
3161 FinalOpcode = Mips::ADDu;
3164 FinalOpcode = Mips::AND;
3166 case (Mips::NORImm):
3167 FinalOpcode = Mips::NOR;
3170 FinalOpcode = Mips::OR;
3173 FinalOpcode = Mips::SLT;
3176 FinalOpcode = Mips::SLTu;
3179 FinalOpcode = Mips::XOR;
3183 if (FinalDstReg == Mips::NoRegister)
3184 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3186 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3193 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3194 SmallVectorImpl<MCInst> &Instructions) {
3195 if (hasShortDelaySlot)
3196 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3198 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3201 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3202 unsigned TrgReg, bool Is64Bit,
3203 SmallVectorImpl<MCInst> &Instructions) {
3204 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3208 void MipsAsmParser::createCpRestoreMemOp(
3209 bool IsLoad, int StackOffset, SMLoc IDLoc,
3210 SmallVectorImpl<MCInst> &Instructions) {
3211 // If the offset can not fit into 16 bits, we need to expand.
3212 if (!isInt<16>(StackOffset)) {
3214 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3215 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3216 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3217 MemInst.addOperand(MCOperand::createImm(StackOffset));
3218 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3222 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3226 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3227 // As described by the Mips32r2 spec, the registers Rd and Rs for
3228 // jalr.hb must be different.
3229 unsigned Opcode = Inst.getOpcode();
3231 if (Opcode == Mips::JALR_HB &&
3232 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3233 return Match_RequiresDifferentSrcAndDst;
3235 return Match_Success;
3238 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3239 OperandVector &Operands,
3241 uint64_t &ErrorInfo,
3242 bool MatchingInlineAsm) {
3245 SmallVector<MCInst, 8> Instructions;
3246 unsigned MatchResult =
3247 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3249 switch (MatchResult) {
3250 case Match_Success: {
3251 if (processInstruction(Inst, IDLoc, Instructions))
3253 for (unsigned i = 0; i < Instructions.size(); i++)
3254 Out.EmitInstruction(Instructions[i], STI);
3257 case Match_MissingFeature:
3258 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3260 case Match_InvalidOperand: {
3261 SMLoc ErrorLoc = IDLoc;
3262 if (ErrorInfo != ~0ULL) {
3263 if (ErrorInfo >= Operands.size())
3264 return Error(IDLoc, "too few operands for instruction");
3266 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3267 if (ErrorLoc == SMLoc())
3271 return Error(ErrorLoc, "invalid operand for instruction");
3273 case Match_MnemonicFail:
3274 return Error(IDLoc, "invalid instruction");
3275 case Match_RequiresDifferentSrcAndDst:
3276 return Error(IDLoc, "source and destination must be different");
3279 llvm_unreachable("Implement any new match types added!");
3282 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3283 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3284 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3285 ") without \".set noat\"");
3288 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3289 if (!AssemblerOptions.back()->isMacro())
3290 Warning(Loc, "macro instruction expanded into multiple instructions");
3294 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3295 SMRange Range, bool ShowColors) {
3296 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3297 Range, SMFixIt(Range, FixMsg),
3301 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3304 CC = StringSwitch<unsigned>(Name)
3340 if (!(isABI_N32() || isABI_N64()))
3343 if (12 <= CC && CC <= 15) {
3344 // Name is one of t4-t7
3345 AsmToken RegTok = getLexer().peekTok();
3346 SMRange RegRange = RegTok.getLocRange();
3348 StringRef FixedName = StringSwitch<StringRef>(Name)
3354 assert(FixedName != "" && "Register name is not one of t4-t7.");
3356 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3357 "Did you mean $" + FixedName + "?", RegRange);
3360 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3361 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3362 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3363 if (8 <= CC && CC <= 11)
3367 CC = StringSwitch<unsigned>(Name)
3379 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3382 CC = StringSwitch<unsigned>(Name)
3383 .Case("hwr_cpunum", 0)
3384 .Case("hwr_synci_step", 1)
3386 .Case("hwr_ccres", 3)
3387 .Case("hwr_ulr", 29)
3393 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3395 if (Name[0] == 'f') {
3396 StringRef NumString = Name.substr(1);
3398 if (NumString.getAsInteger(10, IntVal))
3399 return -1; // This is not an integer.
3400 if (IntVal > 31) // Maximum index for fpu register.
3407 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3409 if (Name.startswith("fcc")) {
3410 StringRef NumString = Name.substr(3);
3412 if (NumString.getAsInteger(10, IntVal))
3413 return -1; // This is not an integer.
3414 if (IntVal > 7) // There are only 8 fcc registers.
3421 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3423 if (Name.startswith("ac")) {
3424 StringRef NumString = Name.substr(2);
3426 if (NumString.getAsInteger(10, IntVal))
3427 return -1; // This is not an integer.
3428 if (IntVal > 3) // There are only 3 acc registers.
3435 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3438 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3447 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3450 CC = StringSwitch<unsigned>(Name)
3453 .Case("msaaccess", 2)
3455 .Case("msamodify", 4)
3456 .Case("msarequest", 5)
3458 .Case("msaunmap", 7)
3464 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3465 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3467 reportParseError(Loc,
3468 "pseudo-instruction requires $at, which is not available");
3471 unsigned AT = getReg(
3472 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3476 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3477 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3480 unsigned MipsAsmParser::getGPR(int RegNo) {
3481 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3485 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3487 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3490 return getReg(RegClass, RegNum);
3493 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3494 MCAsmParser &Parser = getParser();
3495 DEBUG(dbgs() << "parseOperand\n");
3497 // Check if the current operand has a custom associated parser, if so, try to
3498 // custom parse the operand, or fallback to the general approach.
3499 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3500 if (ResTy == MatchOperand_Success)
3502 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3503 // there was a match, but an error occurred, in which case, just return that
3504 // the operand parsing failed.
3505 if (ResTy == MatchOperand_ParseFail)
3508 DEBUG(dbgs() << ".. Generic Parser\n");
3510 switch (getLexer().getKind()) {
3512 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3514 case AsmToken::Dollar: {
3515 // Parse the register.
3516 SMLoc S = Parser.getTok().getLoc();
3518 // Almost all registers have been parsed by custom parsers. There is only
3519 // one exception to this. $zero (and it's alias $0) will reach this point
3520 // for div, divu, and similar instructions because it is not an operand
3521 // to the instruction definition but an explicit register. Special case
3522 // this situation for now.
3523 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3526 // Maybe it is a symbol reference.
3527 StringRef Identifier;
3528 if (Parser.parseIdentifier(Identifier))
3531 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3532 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3533 // Otherwise create a symbol reference.
3535 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3537 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3540 // Else drop to expression parsing.
3541 case AsmToken::LParen:
3542 case AsmToken::Minus:
3543 case AsmToken::Plus:
3544 case AsmToken::Integer:
3545 case AsmToken::Tilde:
3546 case AsmToken::String: {
3547 DEBUG(dbgs() << ".. generic integer\n");
3548 OperandMatchResultTy ResTy = parseImm(Operands);
3549 return ResTy != MatchOperand_Success;
3551 case AsmToken::Percent: {
3552 // It is a symbol reference or constant expression.
3553 const MCExpr *IdVal;
3554 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3555 if (parseRelocOperand(IdVal))
3558 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3560 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3562 } // case AsmToken::Percent
3563 } // switch(getLexer().getKind())
3567 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3568 StringRef RelocStr) {
3570 // Check the type of the expression.
3571 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3572 // It's a constant, evaluate reloc value.
3574 switch (getVariantKind(RelocStr)) {
3575 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3576 // Get the 1st 16-bits.
3577 Val = MCE->getValue() & 0xffff;
3579 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3580 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3581 // 16 bits being negative.
3582 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3584 case MCSymbolRefExpr::VK_Mips_HIGHER:
3585 // Get the 3rd 16-bits.
3586 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3588 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3589 // Get the 4th 16-bits.
3590 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3593 report_fatal_error("unsupported reloc value");
3595 return MCConstantExpr::create(Val, getContext());
3598 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3599 // It's a symbol, create a symbolic expression from the symbol.
3600 const MCSymbol *Symbol = &MSRE->getSymbol();
3601 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3602 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3606 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3607 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3609 // Try to create target expression.
3610 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3611 return MipsMCExpr::create(VK, Expr, getContext());
3613 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3614 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3615 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3619 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3620 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3621 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3624 // Just return the original expression.
3628 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3630 switch (Expr->getKind()) {
3631 case MCExpr::Constant:
3633 case MCExpr::SymbolRef:
3634 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3635 case MCExpr::Binary:
3636 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3637 if (!isEvaluated(BE->getLHS()))
3639 return isEvaluated(BE->getRHS());
3642 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3643 case MCExpr::Target:
3649 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3650 MCAsmParser &Parser = getParser();
3651 Parser.Lex(); // Eat the % token.
3652 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3653 if (Tok.isNot(AsmToken::Identifier))
3656 std::string Str = Tok.getIdentifier();
3658 Parser.Lex(); // Eat the identifier.
3659 // Now make an expression from the rest of the operand.
3660 const MCExpr *IdVal;
3663 if (getLexer().getKind() == AsmToken::LParen) {
3665 Parser.Lex(); // Eat the '(' token.
3666 if (getLexer().getKind() == AsmToken::Percent) {
3667 Parser.Lex(); // Eat the % token.
3668 const AsmToken &nextTok = Parser.getTok();
3669 if (nextTok.isNot(AsmToken::Identifier))
3672 Str += nextTok.getIdentifier();
3673 Parser.Lex(); // Eat the identifier.
3674 if (getLexer().getKind() != AsmToken::LParen)
3679 if (getParser().parseParenExpression(IdVal, EndLoc))
3682 while (getLexer().getKind() == AsmToken::RParen)
3683 Parser.Lex(); // Eat the ')' token.
3686 return true; // Parenthesis must follow the relocation operand.
3688 Res = evaluateRelocExpr(IdVal, Str);
3692 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3694 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3695 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3696 if (ResTy == MatchOperand_Success) {
3697 assert(Operands.size() == 1);
3698 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3699 StartLoc = Operand.getStartLoc();
3700 EndLoc = Operand.getEndLoc();
3702 // AFAIK, we only support numeric registers and named GPR's in CFI
3704 // Don't worry about eating tokens before failing. Using an unrecognised
3705 // register is a parse error.
3706 if (Operand.isGPRAsmReg()) {
3707 // Resolve to GPR32 or GPR64 appropriately.
3708 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3711 return (RegNo == (unsigned)-1);
3714 assert(Operands.size() == 0);
3715 return (RegNo == (unsigned)-1);
3718 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3719 MCAsmParser &Parser = getParser();
3722 unsigned NumOfLParen = 0;
3724 while (getLexer().getKind() == AsmToken::LParen) {
3729 switch (getLexer().getKind()) {
3732 case AsmToken::Identifier:
3733 case AsmToken::LParen:
3734 case AsmToken::Integer:
3735 case AsmToken::Minus:
3736 case AsmToken::Plus:
3738 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3740 Result = (getParser().parseExpression(Res));
3741 while (getLexer().getKind() == AsmToken::RParen)
3744 case AsmToken::Percent:
3745 Result = parseRelocOperand(Res);
3750 MipsAsmParser::OperandMatchResultTy
3751 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3752 MCAsmParser &Parser = getParser();
3753 DEBUG(dbgs() << "parseMemOperand\n");
3754 const MCExpr *IdVal = nullptr;
3756 bool isParenExpr = false;
3757 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3758 // First operand is the offset.
3759 S = Parser.getTok().getLoc();
3761 if (getLexer().getKind() == AsmToken::LParen) {
3766 if (getLexer().getKind() != AsmToken::Dollar) {
3767 if (parseMemOffset(IdVal, isParenExpr))
3768 return MatchOperand_ParseFail;
3770 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3771 if (Tok.isNot(AsmToken::LParen)) {
3772 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3773 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3775 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3776 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3777 return MatchOperand_Success;
3779 if (Tok.is(AsmToken::EndOfStatement)) {
3781 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3783 // Zero register assumed, add a memory operand with ZERO as its base.
3784 // "Base" will be managed by k_Memory.
3785 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3788 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3789 return MatchOperand_Success;
3791 Error(Parser.getTok().getLoc(), "'(' expected");
3792 return MatchOperand_ParseFail;
3795 Parser.Lex(); // Eat the '(' token.
3798 Res = parseAnyRegister(Operands);
3799 if (Res != MatchOperand_Success)
3802 if (Parser.getTok().isNot(AsmToken::RParen)) {
3803 Error(Parser.getTok().getLoc(), "')' expected");
3804 return MatchOperand_ParseFail;
3807 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3809 Parser.Lex(); // Eat the ')' token.
3812 IdVal = MCConstantExpr::create(0, getContext());
3814 // Replace the register operand with the memory operand.
3815 std::unique_ptr<MipsOperand> op(
3816 static_cast<MipsOperand *>(Operands.back().release()));
3817 // Remove the register from the operands.
3818 // "op" will be managed by k_Memory.
3819 Operands.pop_back();
3820 // Add the memory operand.
3821 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3823 if (IdVal->evaluateAsAbsolute(Imm))
3824 IdVal = MCConstantExpr::create(Imm, getContext());
3825 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3826 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3830 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3831 return MatchOperand_Success;
3834 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3835 MCAsmParser &Parser = getParser();
3836 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3838 SMLoc S = Parser.getTok().getLoc();
3840 if (Sym->isVariable())
3841 Expr = Sym->getVariableValue();
3844 if (Expr->getKind() == MCExpr::SymbolRef) {
3845 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3846 StringRef DefSymbol = Ref->getSymbol().getName();
3847 if (DefSymbol.startswith("$")) {
3848 OperandMatchResultTy ResTy =
3849 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3850 if (ResTy == MatchOperand_Success) {
3853 } else if (ResTy == MatchOperand_ParseFail)
3854 llvm_unreachable("Should never ParseFail");
3857 } else if (Expr->getKind() == MCExpr::Constant) {
3859 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3861 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3868 MipsAsmParser::OperandMatchResultTy
3869 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3870 StringRef Identifier,
3872 int Index = matchCPURegisterName(Identifier);
3874 Operands.push_back(MipsOperand::createGPRReg(
3875 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3876 return MatchOperand_Success;
3879 Index = matchHWRegsRegisterName(Identifier);
3881 Operands.push_back(MipsOperand::createHWRegsReg(
3882 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3883 return MatchOperand_Success;
3886 Index = matchFPURegisterName(Identifier);
3888 Operands.push_back(MipsOperand::createFGRReg(
3889 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3890 return MatchOperand_Success;
3893 Index = matchFCCRegisterName(Identifier);
3895 Operands.push_back(MipsOperand::createFCCReg(
3896 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3897 return MatchOperand_Success;
3900 Index = matchACRegisterName(Identifier);
3902 Operands.push_back(MipsOperand::createACCReg(
3903 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3904 return MatchOperand_Success;
3907 Index = matchMSA128RegisterName(Identifier);
3909 Operands.push_back(MipsOperand::createMSA128Reg(
3910 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3911 return MatchOperand_Success;
3914 Index = matchMSA128CtrlRegisterName(Identifier);
3916 Operands.push_back(MipsOperand::createMSACtrlReg(
3917 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3918 return MatchOperand_Success;
3921 return MatchOperand_NoMatch;
3924 MipsAsmParser::OperandMatchResultTy
3925 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3926 MCAsmParser &Parser = getParser();
3927 auto Token = Parser.getLexer().peekTok(false);
3929 if (Token.is(AsmToken::Identifier)) {
3930 DEBUG(dbgs() << ".. identifier\n");
3931 StringRef Identifier = Token.getIdentifier();
3932 OperandMatchResultTy ResTy =
3933 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3935 } else if (Token.is(AsmToken::Integer)) {
3936 DEBUG(dbgs() << ".. integer\n");
3937 Operands.push_back(MipsOperand::createNumericReg(
3938 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3940 return MatchOperand_Success;
3943 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3945 return MatchOperand_NoMatch;
3948 MipsAsmParser::OperandMatchResultTy
3949 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3950 MCAsmParser &Parser = getParser();
3951 DEBUG(dbgs() << "parseAnyRegister\n");
3953 auto Token = Parser.getTok();
3955 SMLoc S = Token.getLoc();
3957 if (Token.isNot(AsmToken::Dollar)) {
3958 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3959 if (Token.is(AsmToken::Identifier)) {
3960 if (searchSymbolAlias(Operands))
3961 return MatchOperand_Success;
3963 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3964 return MatchOperand_NoMatch;
3966 DEBUG(dbgs() << ".. $\n");
3968 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3969 if (ResTy == MatchOperand_Success) {
3971 Parser.Lex(); // identifier
3976 MipsAsmParser::OperandMatchResultTy
3977 MipsAsmParser::parseImm(OperandVector &Operands) {
3978 MCAsmParser &Parser = getParser();
3979 switch (getLexer().getKind()) {
3981 return MatchOperand_NoMatch;
3982 case AsmToken::LParen:
3983 case AsmToken::Minus:
3984 case AsmToken::Plus:
3985 case AsmToken::Integer:
3986 case AsmToken::Tilde:
3987 case AsmToken::String:
3991 const MCExpr *IdVal;
3992 SMLoc S = Parser.getTok().getLoc();
3993 if (getParser().parseExpression(IdVal))
3994 return MatchOperand_ParseFail;
3996 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3997 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3998 return MatchOperand_Success;
4001 MipsAsmParser::OperandMatchResultTy
4002 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4003 MCAsmParser &Parser = getParser();
4004 DEBUG(dbgs() << "parseJumpTarget\n");
4006 SMLoc S = getLexer().getLoc();
4008 // Integers and expressions are acceptable
4009 OperandMatchResultTy ResTy = parseImm(Operands);
4010 if (ResTy != MatchOperand_NoMatch)
4013 // Registers are a valid target and have priority over symbols.
4014 ResTy = parseAnyRegister(Operands);
4015 if (ResTy != MatchOperand_NoMatch)
4018 const MCExpr *Expr = nullptr;
4019 if (Parser.parseExpression(Expr)) {
4020 // We have no way of knowing if a symbol was consumed so we must ParseFail
4021 return MatchOperand_ParseFail;
4024 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4025 return MatchOperand_Success;
4028 MipsAsmParser::OperandMatchResultTy
4029 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4030 MCAsmParser &Parser = getParser();
4031 const MCExpr *IdVal;
4032 // If the first token is '$' we may have register operand.
4033 if (Parser.getTok().is(AsmToken::Dollar))
4034 return MatchOperand_NoMatch;
4035 SMLoc S = Parser.getTok().getLoc();
4036 if (getParser().parseExpression(IdVal))
4037 return MatchOperand_ParseFail;
4038 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4039 assert(MCE && "Unexpected MCExpr type.");
4040 int64_t Val = MCE->getValue();
4041 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4042 Operands.push_back(MipsOperand::CreateImm(
4043 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4044 return MatchOperand_Success;
4047 MipsAsmParser::OperandMatchResultTy
4048 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4049 MCAsmParser &Parser = getParser();
4050 switch (getLexer().getKind()) {
4052 return MatchOperand_NoMatch;
4053 case AsmToken::LParen:
4054 case AsmToken::Plus:
4055 case AsmToken::Minus:
4056 case AsmToken::Integer:
4061 SMLoc S = Parser.getTok().getLoc();
4063 if (getParser().parseExpression(Expr))
4064 return MatchOperand_ParseFail;
4067 if (!Expr->evaluateAsAbsolute(Val)) {
4068 Error(S, "expected immediate value");
4069 return MatchOperand_ParseFail;
4072 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4073 // and because the CPU always adds one to the immediate field, the allowed
4074 // range becomes 1..4. We'll only check the range here and will deal
4075 // with the addition/subtraction when actually decoding/encoding
4077 if (Val < 1 || Val > 4) {
4078 Error(S, "immediate not in range (1..4)");
4079 return MatchOperand_ParseFail;
4083 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4084 return MatchOperand_Success;
4087 MipsAsmParser::OperandMatchResultTy
4088 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4089 MCAsmParser &Parser = getParser();
4090 SmallVector<unsigned, 10> Regs;
4092 unsigned PrevReg = Mips::NoRegister;
4093 bool RegRange = false;
4094 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4096 if (Parser.getTok().isNot(AsmToken::Dollar))
4097 return MatchOperand_ParseFail;
4099 SMLoc S = Parser.getTok().getLoc();
4100 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4101 SMLoc E = getLexer().getLoc();
4102 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4103 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4105 // Remove last register operand because registers from register range
4106 // should be inserted first.
4107 if (RegNo == Mips::RA) {
4108 Regs.push_back(RegNo);
4110 unsigned TmpReg = PrevReg + 1;
4111 while (TmpReg <= RegNo) {
4112 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4113 Error(E, "invalid register operand");
4114 return MatchOperand_ParseFail;
4118 Regs.push_back(TmpReg++);
4124 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4125 (RegNo != Mips::RA)) {
4126 Error(E, "$16 or $31 expected");
4127 return MatchOperand_ParseFail;
4128 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4129 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4130 Error(E, "invalid register operand");
4131 return MatchOperand_ParseFail;
4132 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4133 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4134 Error(E, "consecutive register numbers expected");
4135 return MatchOperand_ParseFail;
4138 Regs.push_back(RegNo);
4141 if (Parser.getTok().is(AsmToken::Minus))
4144 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4145 !Parser.getTok().isNot(AsmToken::Comma)) {
4146 Error(E, "',' or '-' expected");
4147 return MatchOperand_ParseFail;
4150 Lex(); // Consume comma or minus
4151 if (Parser.getTok().isNot(AsmToken::Dollar))
4157 SMLoc E = Parser.getTok().getLoc();
4158 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4159 parseMemOperand(Operands);
4160 return MatchOperand_Success;
4163 MipsAsmParser::OperandMatchResultTy
4164 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4165 MCAsmParser &Parser = getParser();
4167 SMLoc S = Parser.getTok().getLoc();
4168 if (parseAnyRegister(Operands) != MatchOperand_Success)
4169 return MatchOperand_ParseFail;
4171 SMLoc E = Parser.getTok().getLoc();
4172 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4173 unsigned Reg = Op.getGPR32Reg();
4174 Operands.pop_back();
4175 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4176 return MatchOperand_Success;
4179 MipsAsmParser::OperandMatchResultTy
4180 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4181 MCAsmParser &Parser = getParser();
4182 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4183 SmallVector<unsigned, 10> Regs;
4185 if (Parser.getTok().isNot(AsmToken::Dollar))
4186 return MatchOperand_ParseFail;
4188 SMLoc S = Parser.getTok().getLoc();
4190 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4191 return MatchOperand_ParseFail;
4193 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4194 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4195 Regs.push_back(RegNo);
4197 SMLoc E = Parser.getTok().getLoc();
4198 if (Parser.getTok().isNot(AsmToken::Comma)) {
4199 Error(E, "',' expected");
4200 return MatchOperand_ParseFail;
4206 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4207 return MatchOperand_ParseFail;
4209 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4210 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4211 Regs.push_back(RegNo);
4213 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4215 return MatchOperand_Success;
4218 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4220 MCSymbolRefExpr::VariantKind VK =
4221 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4222 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4223 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4224 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4225 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4226 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4227 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4228 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4229 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4230 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4231 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4232 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4233 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4234 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4235 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4236 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4237 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4238 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4239 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4240 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4241 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4242 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4243 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4244 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4245 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4246 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4247 .Default(MCSymbolRefExpr::VK_None);
4249 assert(VK != MCSymbolRefExpr::VK_None);
4254 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4256 /// ::= '(', register, ')'
4257 /// handle it before we iterate so we don't get tripped up by the lack of
4259 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4260 MCAsmParser &Parser = getParser();
4261 if (getLexer().is(AsmToken::LParen)) {
4263 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4265 if (parseOperand(Operands, Name)) {
4266 SMLoc Loc = getLexer().getLoc();
4267 Parser.eatToEndOfStatement();
4268 return Error(Loc, "unexpected token in argument list");
4270 if (Parser.getTok().isNot(AsmToken::RParen)) {
4271 SMLoc Loc = getLexer().getLoc();
4272 Parser.eatToEndOfStatement();
4273 return Error(Loc, "unexpected token, expected ')'");
4276 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4282 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4283 /// either one of these.
4284 /// ::= '[', register, ']'
4285 /// ::= '[', integer, ']'
4286 /// handle it before we iterate so we don't get tripped up by the lack of
4288 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4289 OperandVector &Operands) {
4290 MCAsmParser &Parser = getParser();
4291 if (getLexer().is(AsmToken::LBrac)) {
4293 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4295 if (parseOperand(Operands, Name)) {
4296 SMLoc Loc = getLexer().getLoc();
4297 Parser.eatToEndOfStatement();
4298 return Error(Loc, "unexpected token in argument list");
4300 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4301 SMLoc Loc = getLexer().getLoc();
4302 Parser.eatToEndOfStatement();
4303 return Error(Loc, "unexpected token, expected ']'");
4306 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4312 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4313 SMLoc NameLoc, OperandVector &Operands) {
4314 MCAsmParser &Parser = getParser();
4315 DEBUG(dbgs() << "ParseInstruction\n");
4317 // We have reached first instruction, module directive are now forbidden.
4318 getTargetStreamer().forbidModuleDirective();
4320 // Check if we have valid mnemonic
4321 if (!mnemonicIsValid(Name, 0)) {
4322 Parser.eatToEndOfStatement();
4323 return Error(NameLoc, "unknown instruction");
4325 // First operand in MCInst is instruction mnemonic.
4326 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4328 // Read the remaining operands.
4329 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4330 // Read the first operand.
4331 if (parseOperand(Operands, Name)) {
4332 SMLoc Loc = getLexer().getLoc();
4333 Parser.eatToEndOfStatement();
4334 return Error(Loc, "unexpected token in argument list");
4336 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4338 // AFAIK, parenthesis suffixes are never on the first operand
4340 while (getLexer().is(AsmToken::Comma)) {
4341 Parser.Lex(); // Eat the comma.
4342 // Parse and remember the operand.
4343 if (parseOperand(Operands, Name)) {
4344 SMLoc Loc = getLexer().getLoc();
4345 Parser.eatToEndOfStatement();
4346 return Error(Loc, "unexpected token in argument list");
4348 // Parse bracket and parenthesis suffixes before we iterate
4349 if (getLexer().is(AsmToken::LBrac)) {
4350 if (parseBracketSuffix(Name, Operands))
4352 } else if (getLexer().is(AsmToken::LParen) &&
4353 parseParenSuffix(Name, Operands))
4357 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4358 SMLoc Loc = getLexer().getLoc();
4359 Parser.eatToEndOfStatement();
4360 return Error(Loc, "unexpected token in argument list");
4362 Parser.Lex(); // Consume the EndOfStatement.
4366 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4367 MCAsmParser &Parser = getParser();
4368 SMLoc Loc = getLexer().getLoc();
4369 Parser.eatToEndOfStatement();
4370 return Error(Loc, ErrorMsg);
4373 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4374 return Error(Loc, ErrorMsg);
4377 bool MipsAsmParser::parseSetNoAtDirective() {
4378 MCAsmParser &Parser = getParser();
4379 // Line should look like: ".set noat".
4381 // Set the $at register to $0.
4382 AssemblerOptions.back()->setATRegIndex(0);
4384 Parser.Lex(); // Eat "noat".
4386 // If this is not the end of the statement, report an error.
4387 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4388 reportParseError("unexpected token, expected end of statement");
4392 getTargetStreamer().emitDirectiveSetNoAt();
4393 Parser.Lex(); // Consume the EndOfStatement.
4397 bool MipsAsmParser::parseSetAtDirective() {
4398 // Line can be: ".set at", which sets $at to $1
4399 // or ".set at=$reg", which sets $at to $reg.
4400 MCAsmParser &Parser = getParser();
4401 Parser.Lex(); // Eat "at".
4403 if (getLexer().is(AsmToken::EndOfStatement)) {
4404 // No register was specified, so we set $at to $1.
4405 AssemblerOptions.back()->setATRegIndex(1);
4407 getTargetStreamer().emitDirectiveSetAt();
4408 Parser.Lex(); // Consume the EndOfStatement.
4412 if (getLexer().isNot(AsmToken::Equal)) {
4413 reportParseError("unexpected token, expected equals sign");
4416 Parser.Lex(); // Eat "=".
4418 if (getLexer().isNot(AsmToken::Dollar)) {
4419 if (getLexer().is(AsmToken::EndOfStatement)) {
4420 reportParseError("no register specified");
4423 reportParseError("unexpected token, expected dollar sign '$'");
4427 Parser.Lex(); // Eat "$".
4429 // Find out what "reg" is.
4431 const AsmToken &Reg = Parser.getTok();
4432 if (Reg.is(AsmToken::Identifier)) {
4433 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4434 } else if (Reg.is(AsmToken::Integer)) {
4435 AtRegNo = Reg.getIntVal();
4437 reportParseError("unexpected token, expected identifier or integer");
4441 // Check if $reg is a valid register. If it is, set $at to $reg.
4442 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4443 reportParseError("invalid register");
4446 Parser.Lex(); // Eat "reg".
4448 // If this is not the end of the statement, report an error.
4449 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4450 reportParseError("unexpected token, expected end of statement");
4454 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4456 Parser.Lex(); // Consume the EndOfStatement.
4460 bool MipsAsmParser::parseSetReorderDirective() {
4461 MCAsmParser &Parser = getParser();
4463 // If this is not the end of the statement, report an error.
4464 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4465 reportParseError("unexpected token, expected end of statement");
4468 AssemblerOptions.back()->setReorder();
4469 getTargetStreamer().emitDirectiveSetReorder();
4470 Parser.Lex(); // Consume the EndOfStatement.
4474 bool MipsAsmParser::parseSetNoReorderDirective() {
4475 MCAsmParser &Parser = getParser();
4477 // If this is not the end of the statement, report an error.
4478 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4479 reportParseError("unexpected token, expected end of statement");
4482 AssemblerOptions.back()->setNoReorder();
4483 getTargetStreamer().emitDirectiveSetNoReorder();
4484 Parser.Lex(); // Consume the EndOfStatement.
4488 bool MipsAsmParser::parseSetMacroDirective() {
4489 MCAsmParser &Parser = getParser();
4491 // If this is not the end of the statement, report an error.
4492 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4493 reportParseError("unexpected token, expected end of statement");
4496 AssemblerOptions.back()->setMacro();
4497 getTargetStreamer().emitDirectiveSetMacro();
4498 Parser.Lex(); // Consume the EndOfStatement.
4502 bool MipsAsmParser::parseSetNoMacroDirective() {
4503 MCAsmParser &Parser = getParser();
4505 // If this is not the end of the statement, report an error.
4506 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4507 reportParseError("unexpected token, expected end of statement");
4510 if (AssemblerOptions.back()->isReorder()) {
4511 reportParseError("`noreorder' must be set before `nomacro'");
4514 AssemblerOptions.back()->setNoMacro();
4515 getTargetStreamer().emitDirectiveSetNoMacro();
4516 Parser.Lex(); // Consume the EndOfStatement.
4520 bool MipsAsmParser::parseSetMsaDirective() {
4521 MCAsmParser &Parser = getParser();
4524 // If this is not the end of the statement, report an error.
4525 if (getLexer().isNot(AsmToken::EndOfStatement))
4526 return reportParseError("unexpected token, expected end of statement");
4528 setFeatureBits(Mips::FeatureMSA, "msa");
4529 getTargetStreamer().emitDirectiveSetMsa();
4533 bool MipsAsmParser::parseSetNoMsaDirective() {
4534 MCAsmParser &Parser = getParser();
4537 // If this is not the end of the statement, report an error.
4538 if (getLexer().isNot(AsmToken::EndOfStatement))
4539 return reportParseError("unexpected token, expected end of statement");
4541 clearFeatureBits(Mips::FeatureMSA, "msa");
4542 getTargetStreamer().emitDirectiveSetNoMsa();
4546 bool MipsAsmParser::parseSetNoDspDirective() {
4547 MCAsmParser &Parser = getParser();
4548 Parser.Lex(); // Eat "nodsp".
4550 // If this is not the end of the statement, report an error.
4551 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4552 reportParseError("unexpected token, expected end of statement");
4556 clearFeatureBits(Mips::FeatureDSP, "dsp");
4557 getTargetStreamer().emitDirectiveSetNoDsp();
4561 bool MipsAsmParser::parseSetMips16Directive() {
4562 MCAsmParser &Parser = getParser();
4563 Parser.Lex(); // Eat "mips16".
4565 // If this is not the end of the statement, report an error.
4566 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4567 reportParseError("unexpected token, expected end of statement");
4571 setFeatureBits(Mips::FeatureMips16, "mips16");
4572 getTargetStreamer().emitDirectiveSetMips16();
4573 Parser.Lex(); // Consume the EndOfStatement.
4577 bool MipsAsmParser::parseSetNoMips16Directive() {
4578 MCAsmParser &Parser = getParser();
4579 Parser.Lex(); // Eat "nomips16".
4581 // If this is not the end of the statement, report an error.
4582 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4583 reportParseError("unexpected token, expected end of statement");
4587 clearFeatureBits(Mips::FeatureMips16, "mips16");
4588 getTargetStreamer().emitDirectiveSetNoMips16();
4589 Parser.Lex(); // Consume the EndOfStatement.
4593 bool MipsAsmParser::parseSetFpDirective() {
4594 MCAsmParser &Parser = getParser();
4595 MipsABIFlagsSection::FpABIKind FpAbiVal;
4596 // Line can be: .set fp=32
4599 Parser.Lex(); // Eat fp token
4600 AsmToken Tok = Parser.getTok();
4601 if (Tok.isNot(AsmToken::Equal)) {
4602 reportParseError("unexpected token, expected equals sign '='");
4605 Parser.Lex(); // Eat '=' token.
4606 Tok = Parser.getTok();
4608 if (!parseFpABIValue(FpAbiVal, ".set"))
4611 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4612 reportParseError("unexpected token, expected end of statement");
4615 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4616 Parser.Lex(); // Consume the EndOfStatement.
4620 bool MipsAsmParser::parseSetOddSPRegDirective() {
4621 MCAsmParser &Parser = getParser();
4623 Parser.Lex(); // Eat "oddspreg".
4624 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4625 reportParseError("unexpected token, expected end of statement");
4629 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4630 getTargetStreamer().emitDirectiveSetOddSPReg();
4634 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4635 MCAsmParser &Parser = getParser();
4637 Parser.Lex(); // Eat "nooddspreg".
4638 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4639 reportParseError("unexpected token, expected end of statement");
4643 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4644 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4648 bool MipsAsmParser::parseSetPopDirective() {
4649 MCAsmParser &Parser = getParser();
4650 SMLoc Loc = getLexer().getLoc();
4653 if (getLexer().isNot(AsmToken::EndOfStatement))
4654 return reportParseError("unexpected token, expected end of statement");
4656 // Always keep an element on the options "stack" to prevent the user
4657 // from changing the initial options. This is how we remember them.
4658 if (AssemblerOptions.size() == 2)
4659 return reportParseError(Loc, ".set pop with no .set push");
4661 AssemblerOptions.pop_back();
4662 setAvailableFeatures(
4663 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4664 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4666 getTargetStreamer().emitDirectiveSetPop();
4670 bool MipsAsmParser::parseSetPushDirective() {
4671 MCAsmParser &Parser = getParser();
4673 if (getLexer().isNot(AsmToken::EndOfStatement))
4674 return reportParseError("unexpected token, expected end of statement");
4676 // Create a copy of the current assembler options environment and push it.
4677 AssemblerOptions.push_back(
4678 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4680 getTargetStreamer().emitDirectiveSetPush();
4684 bool MipsAsmParser::parseSetSoftFloatDirective() {
4685 MCAsmParser &Parser = getParser();
4687 if (getLexer().isNot(AsmToken::EndOfStatement))
4688 return reportParseError("unexpected token, expected end of statement");
4690 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4691 getTargetStreamer().emitDirectiveSetSoftFloat();
4695 bool MipsAsmParser::parseSetHardFloatDirective() {
4696 MCAsmParser &Parser = getParser();
4698 if (getLexer().isNot(AsmToken::EndOfStatement))
4699 return reportParseError("unexpected token, expected end of statement");
4701 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4702 getTargetStreamer().emitDirectiveSetHardFloat();
4706 bool MipsAsmParser::parseSetAssignment() {
4708 const MCExpr *Value;
4709 MCAsmParser &Parser = getParser();
4711 if (Parser.parseIdentifier(Name))
4712 reportParseError("expected identifier after .set");
4714 if (getLexer().isNot(AsmToken::Comma))
4715 return reportParseError("unexpected token, expected comma");
4718 if (Parser.parseExpression(Value))
4719 return reportParseError("expected valid expression after comma");
4721 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4722 Sym->setVariableValue(Value);
4727 bool MipsAsmParser::parseSetMips0Directive() {
4728 MCAsmParser &Parser = getParser();
4730 if (getLexer().isNot(AsmToken::EndOfStatement))
4731 return reportParseError("unexpected token, expected end of statement");
4733 // Reset assembler options to their initial values.
4734 setAvailableFeatures(
4735 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4736 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4737 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4739 getTargetStreamer().emitDirectiveSetMips0();
4743 bool MipsAsmParser::parseSetArchDirective() {
4744 MCAsmParser &Parser = getParser();
4746 if (getLexer().isNot(AsmToken::Equal))
4747 return reportParseError("unexpected token, expected equals sign");
4751 if (Parser.parseIdentifier(Arch))
4752 return reportParseError("expected arch identifier");
4754 StringRef ArchFeatureName =
4755 StringSwitch<StringRef>(Arch)
4756 .Case("mips1", "mips1")
4757 .Case("mips2", "mips2")
4758 .Case("mips3", "mips3")
4759 .Case("mips4", "mips4")
4760 .Case("mips5", "mips5")
4761 .Case("mips32", "mips32")
4762 .Case("mips32r2", "mips32r2")
4763 .Case("mips32r3", "mips32r3")
4764 .Case("mips32r5", "mips32r5")
4765 .Case("mips32r6", "mips32r6")
4766 .Case("mips64", "mips64")
4767 .Case("mips64r2", "mips64r2")
4768 .Case("mips64r3", "mips64r3")
4769 .Case("mips64r5", "mips64r5")
4770 .Case("mips64r6", "mips64r6")
4771 .Case("cnmips", "cnmips")
4772 .Case("r4000", "mips3") // This is an implementation of Mips3.
4775 if (ArchFeatureName.empty())
4776 return reportParseError("unsupported architecture");
4778 selectArch(ArchFeatureName);
4779 getTargetStreamer().emitDirectiveSetArch(Arch);
4783 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4784 MCAsmParser &Parser = getParser();
4786 if (getLexer().isNot(AsmToken::EndOfStatement))
4787 return reportParseError("unexpected token, expected end of statement");
4791 llvm_unreachable("Unimplemented feature");
4792 case Mips::FeatureDSP:
4793 setFeatureBits(Mips::FeatureDSP, "dsp");
4794 getTargetStreamer().emitDirectiveSetDsp();
4796 case Mips::FeatureMicroMips:
4797 getTargetStreamer().emitDirectiveSetMicroMips();
4799 case Mips::FeatureMips1:
4800 selectArch("mips1");
4801 getTargetStreamer().emitDirectiveSetMips1();
4803 case Mips::FeatureMips2:
4804 selectArch("mips2");
4805 getTargetStreamer().emitDirectiveSetMips2();
4807 case Mips::FeatureMips3:
4808 selectArch("mips3");
4809 getTargetStreamer().emitDirectiveSetMips3();
4811 case Mips::FeatureMips4:
4812 selectArch("mips4");
4813 getTargetStreamer().emitDirectiveSetMips4();
4815 case Mips::FeatureMips5:
4816 selectArch("mips5");
4817 getTargetStreamer().emitDirectiveSetMips5();
4819 case Mips::FeatureMips32:
4820 selectArch("mips32");
4821 getTargetStreamer().emitDirectiveSetMips32();
4823 case Mips::FeatureMips32r2:
4824 selectArch("mips32r2");
4825 getTargetStreamer().emitDirectiveSetMips32R2();
4827 case Mips::FeatureMips32r3:
4828 selectArch("mips32r3");
4829 getTargetStreamer().emitDirectiveSetMips32R3();
4831 case Mips::FeatureMips32r5:
4832 selectArch("mips32r5");
4833 getTargetStreamer().emitDirectiveSetMips32R5();
4835 case Mips::FeatureMips32r6:
4836 selectArch("mips32r6");
4837 getTargetStreamer().emitDirectiveSetMips32R6();
4839 case Mips::FeatureMips64:
4840 selectArch("mips64");
4841 getTargetStreamer().emitDirectiveSetMips64();
4843 case Mips::FeatureMips64r2:
4844 selectArch("mips64r2");
4845 getTargetStreamer().emitDirectiveSetMips64R2();
4847 case Mips::FeatureMips64r3:
4848 selectArch("mips64r3");
4849 getTargetStreamer().emitDirectiveSetMips64R3();
4851 case Mips::FeatureMips64r5:
4852 selectArch("mips64r5");
4853 getTargetStreamer().emitDirectiveSetMips64R5();
4855 case Mips::FeatureMips64r6:
4856 selectArch("mips64r6");
4857 getTargetStreamer().emitDirectiveSetMips64R6();
4863 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4864 MCAsmParser &Parser = getParser();
4865 if (getLexer().isNot(AsmToken::Comma)) {
4866 SMLoc Loc = getLexer().getLoc();
4867 Parser.eatToEndOfStatement();
4868 return Error(Loc, ErrorStr);
4871 Parser.Lex(); // Eat the comma.
4875 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4876 // In this class, it is only used for .cprestore.
4877 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4878 // MipsTargetELFStreamer and MipsAsmParser.
4879 bool MipsAsmParser::isPicAndNotNxxAbi() {
4880 return inPicMode() && !(isABI_N32() || isABI_N64());
4883 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4884 if (AssemblerOptions.back()->isReorder())
4885 Warning(Loc, ".cpload should be inside a noreorder section");
4887 if (inMips16Mode()) {
4888 reportParseError(".cpload is not supported in Mips16 mode");
4892 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4893 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4894 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4895 reportParseError("expected register containing function address");
4899 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4900 if (!RegOpnd.isGPRAsmReg()) {
4901 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4905 // If this is not the end of the statement, report an error.
4906 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4907 reportParseError("unexpected token, expected end of statement");
4911 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4915 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4916 MCAsmParser &Parser = getParser();
4918 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4919 // is used in non-PIC mode.
4921 if (inMips16Mode()) {
4922 reportParseError(".cprestore is not supported in Mips16 mode");
4926 // Get the stack offset value.
4927 const MCExpr *StackOffset;
4928 int64_t StackOffsetVal;
4929 if (Parser.parseExpression(StackOffset)) {
4930 reportParseError("expected stack offset value");
4934 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4935 reportParseError("stack offset is not an absolute expression");
4939 if (StackOffsetVal < 0) {
4940 Warning(Loc, ".cprestore with negative stack offset has no effect");
4941 IsCpRestoreSet = false;
4943 IsCpRestoreSet = true;
4944 CpRestoreOffset = StackOffsetVal;
4947 // If this is not the end of the statement, report an error.
4948 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4949 reportParseError("unexpected token, expected end of statement");
4953 // Store the $gp on the stack.
4954 SmallVector<MCInst, 3> StoreInsts;
4955 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
4958 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
4959 Parser.Lex(); // Consume the EndOfStatement.
4963 bool MipsAsmParser::parseDirectiveCPSetup() {
4964 MCAsmParser &Parser = getParser();
4967 bool SaveIsReg = true;
4969 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4970 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4971 if (ResTy == MatchOperand_NoMatch) {
4972 reportParseError("expected register containing function address");
4973 Parser.eatToEndOfStatement();
4977 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4978 if (!FuncRegOpnd.isGPRAsmReg()) {
4979 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4980 Parser.eatToEndOfStatement();
4984 FuncReg = FuncRegOpnd.getGPR32Reg();
4987 if (!eatComma("unexpected token, expected comma"))
4990 ResTy = parseAnyRegister(TmpReg);
4991 if (ResTy == MatchOperand_NoMatch) {
4992 const MCExpr *OffsetExpr;
4994 SMLoc ExprLoc = getLexer().getLoc();
4996 if (Parser.parseExpression(OffsetExpr) ||
4997 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
4998 reportParseError(ExprLoc, "expected save register or stack offset");
4999 Parser.eatToEndOfStatement();
5006 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5007 if (!SaveOpnd.isGPRAsmReg()) {
5008 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5009 Parser.eatToEndOfStatement();
5012 Save = SaveOpnd.getGPR32Reg();
5015 if (!eatComma("unexpected token, expected comma"))
5019 if (Parser.parseExpression(Expr)) {
5020 reportParseError("expected expression");
5024 if (Expr->getKind() != MCExpr::SymbolRef) {
5025 reportParseError("expected symbol");
5028 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5030 CpSaveLocation = Save;
5031 CpSaveLocationIsRegister = SaveIsReg;
5033 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5038 bool MipsAsmParser::parseDirectiveCPReturn() {
5039 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5040 CpSaveLocationIsRegister);
5044 bool MipsAsmParser::parseDirectiveNaN() {
5045 MCAsmParser &Parser = getParser();
5046 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5047 const AsmToken &Tok = Parser.getTok();
5049 if (Tok.getString() == "2008") {
5051 getTargetStreamer().emitDirectiveNaN2008();
5053 } else if (Tok.getString() == "legacy") {
5055 getTargetStreamer().emitDirectiveNaNLegacy();
5059 // If we don't recognize the option passed to the .nan
5060 // directive (e.g. no option or unknown option), emit an error.
5061 reportParseError("invalid option in .nan directive");
5065 bool MipsAsmParser::parseDirectiveSet() {
5066 MCAsmParser &Parser = getParser();
5067 // Get the next token.
5068 const AsmToken &Tok = Parser.getTok();
5070 if (Tok.getString() == "noat") {
5071 return parseSetNoAtDirective();
5072 } else if (Tok.getString() == "at") {
5073 return parseSetAtDirective();
5074 } else if (Tok.getString() == "arch") {
5075 return parseSetArchDirective();
5076 } else if (Tok.getString() == "fp") {
5077 return parseSetFpDirective();
5078 } else if (Tok.getString() == "oddspreg") {
5079 return parseSetOddSPRegDirective();
5080 } else if (Tok.getString() == "nooddspreg") {
5081 return parseSetNoOddSPRegDirective();
5082 } else if (Tok.getString() == "pop") {
5083 return parseSetPopDirective();
5084 } else if (Tok.getString() == "push") {
5085 return parseSetPushDirective();
5086 } else if (Tok.getString() == "reorder") {
5087 return parseSetReorderDirective();
5088 } else if (Tok.getString() == "noreorder") {
5089 return parseSetNoReorderDirective();
5090 } else if (Tok.getString() == "macro") {
5091 return parseSetMacroDirective();
5092 } else if (Tok.getString() == "nomacro") {
5093 return parseSetNoMacroDirective();
5094 } else if (Tok.getString() == "mips16") {
5095 return parseSetMips16Directive();
5096 } else if (Tok.getString() == "nomips16") {
5097 return parseSetNoMips16Directive();
5098 } else if (Tok.getString() == "nomicromips") {
5099 getTargetStreamer().emitDirectiveSetNoMicroMips();
5100 Parser.eatToEndOfStatement();
5102 } else if (Tok.getString() == "micromips") {
5103 return parseSetFeature(Mips::FeatureMicroMips);
5104 } else if (Tok.getString() == "mips0") {
5105 return parseSetMips0Directive();
5106 } else if (Tok.getString() == "mips1") {
5107 return parseSetFeature(Mips::FeatureMips1);
5108 } else if (Tok.getString() == "mips2") {
5109 return parseSetFeature(Mips::FeatureMips2);
5110 } else if (Tok.getString() == "mips3") {
5111 return parseSetFeature(Mips::FeatureMips3);
5112 } else if (Tok.getString() == "mips4") {
5113 return parseSetFeature(Mips::FeatureMips4);
5114 } else if (Tok.getString() == "mips5") {
5115 return parseSetFeature(Mips::FeatureMips5);
5116 } else if (Tok.getString() == "mips32") {
5117 return parseSetFeature(Mips::FeatureMips32);
5118 } else if (Tok.getString() == "mips32r2") {
5119 return parseSetFeature(Mips::FeatureMips32r2);
5120 } else if (Tok.getString() == "mips32r3") {
5121 return parseSetFeature(Mips::FeatureMips32r3);
5122 } else if (Tok.getString() == "mips32r5") {
5123 return parseSetFeature(Mips::FeatureMips32r5);
5124 } else if (Tok.getString() == "mips32r6") {
5125 return parseSetFeature(Mips::FeatureMips32r6);
5126 } else if (Tok.getString() == "mips64") {
5127 return parseSetFeature(Mips::FeatureMips64);
5128 } else if (Tok.getString() == "mips64r2") {
5129 return parseSetFeature(Mips::FeatureMips64r2);
5130 } else if (Tok.getString() == "mips64r3") {
5131 return parseSetFeature(Mips::FeatureMips64r3);
5132 } else if (Tok.getString() == "mips64r5") {
5133 return parseSetFeature(Mips::FeatureMips64r5);
5134 } else if (Tok.getString() == "mips64r6") {
5135 return parseSetFeature(Mips::FeatureMips64r6);
5136 } else if (Tok.getString() == "dsp") {
5137 return parseSetFeature(Mips::FeatureDSP);
5138 } else if (Tok.getString() == "nodsp") {
5139 return parseSetNoDspDirective();
5140 } else if (Tok.getString() == "msa") {
5141 return parseSetMsaDirective();
5142 } else if (Tok.getString() == "nomsa") {
5143 return parseSetNoMsaDirective();
5144 } else if (Tok.getString() == "softfloat") {
5145 return parseSetSoftFloatDirective();
5146 } else if (Tok.getString() == "hardfloat") {
5147 return parseSetHardFloatDirective();
5149 // It is just an identifier, look for an assignment.
5150 parseSetAssignment();
5157 /// parseDataDirective
5158 /// ::= .word [ expression (, expression)* ]
5159 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5160 MCAsmParser &Parser = getParser();
5161 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5163 const MCExpr *Value;
5164 if (getParser().parseExpression(Value))
5167 getParser().getStreamer().EmitValue(Value, Size);
5169 if (getLexer().is(AsmToken::EndOfStatement))
5172 if (getLexer().isNot(AsmToken::Comma))
5173 return Error(L, "unexpected token, expected comma");
5182 /// parseDirectiveGpWord
5183 /// ::= .gpword local_sym
5184 bool MipsAsmParser::parseDirectiveGpWord() {
5185 MCAsmParser &Parser = getParser();
5186 const MCExpr *Value;
5187 // EmitGPRel32Value requires an expression, so we are using base class
5188 // method to evaluate the expression.
5189 if (getParser().parseExpression(Value))
5191 getParser().getStreamer().EmitGPRel32Value(Value);
5193 if (getLexer().isNot(AsmToken::EndOfStatement))
5194 return Error(getLexer().getLoc(),
5195 "unexpected token, expected end of statement");
5196 Parser.Lex(); // Eat EndOfStatement token.
5200 /// parseDirectiveGpDWord
5201 /// ::= .gpdword local_sym
5202 bool MipsAsmParser::parseDirectiveGpDWord() {
5203 MCAsmParser &Parser = getParser();
5204 const MCExpr *Value;
5205 // EmitGPRel64Value requires an expression, so we are using base class
5206 // method to evaluate the expression.
5207 if (getParser().parseExpression(Value))
5209 getParser().getStreamer().EmitGPRel64Value(Value);
5211 if (getLexer().isNot(AsmToken::EndOfStatement))
5212 return Error(getLexer().getLoc(),
5213 "unexpected token, expected end of statement");
5214 Parser.Lex(); // Eat EndOfStatement token.
5218 bool MipsAsmParser::parseDirectiveOption() {
5219 MCAsmParser &Parser = getParser();
5220 // Get the option token.
5221 AsmToken Tok = Parser.getTok();
5222 // At the moment only identifiers are supported.
5223 if (Tok.isNot(AsmToken::Identifier)) {
5224 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5225 Parser.eatToEndOfStatement();
5229 StringRef Option = Tok.getIdentifier();
5231 if (Option == "pic0") {
5232 // MipsAsmParser needs to know if the current PIC mode changes.
5233 IsPicEnabled = false;
5235 getTargetStreamer().emitDirectiveOptionPic0();
5237 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5238 Error(Parser.getTok().getLoc(),
5239 "unexpected token, expected end of statement");
5240 Parser.eatToEndOfStatement();
5245 if (Option == "pic2") {
5246 // MipsAsmParser needs to know if the current PIC mode changes.
5247 IsPicEnabled = true;
5249 getTargetStreamer().emitDirectiveOptionPic2();
5251 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5252 Error(Parser.getTok().getLoc(),
5253 "unexpected token, expected end of statement");
5254 Parser.eatToEndOfStatement();
5260 Warning(Parser.getTok().getLoc(),
5261 "unknown option, expected 'pic0' or 'pic2'");
5262 Parser.eatToEndOfStatement();
5266 /// parseInsnDirective
5268 bool MipsAsmParser::parseInsnDirective() {
5269 // If this is not the end of the statement, report an error.
5270 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5271 reportParseError("unexpected token, expected end of statement");
5275 // The actual label marking happens in
5276 // MipsELFStreamer::createPendingLabelRelocs().
5277 getTargetStreamer().emitDirectiveInsn();
5279 getParser().Lex(); // Eat EndOfStatement token.
5283 /// parseDirectiveModule
5284 /// ::= .module oddspreg
5285 /// ::= .module nooddspreg
5286 /// ::= .module fp=value
5287 /// ::= .module softfloat
5288 /// ::= .module hardfloat
5289 bool MipsAsmParser::parseDirectiveModule() {
5290 MCAsmParser &Parser = getParser();
5291 MCAsmLexer &Lexer = getLexer();
5292 SMLoc L = Lexer.getLoc();
5294 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5295 // TODO : get a better message.
5296 reportParseError(".module directive must appear before any code");
5301 if (Parser.parseIdentifier(Option)) {
5302 reportParseError("expected .module option identifier");
5306 if (Option == "oddspreg") {
5307 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5309 // Synchronize the abiflags information with the FeatureBits information we
5311 getTargetStreamer().updateABIInfo(*this);
5313 // If printing assembly, use the recently updated abiflags information.
5314 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5315 // emitted at the end).
5316 getTargetStreamer().emitDirectiveModuleOddSPReg();
5318 // If this is not the end of the statement, report an error.
5319 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5320 reportParseError("unexpected token, expected end of statement");
5324 return false; // parseDirectiveModule has finished successfully.
5325 } else if (Option == "nooddspreg") {
5327 Error(L, "'.module nooddspreg' requires the O32 ABI");
5331 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5333 // Synchronize the abiflags information with the FeatureBits information we
5335 getTargetStreamer().updateABIInfo(*this);
5337 // If printing assembly, use the recently updated abiflags information.
5338 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5339 // emitted at the end).
5340 getTargetStreamer().emitDirectiveModuleOddSPReg();
5342 // If this is not the end of the statement, report an error.
5343 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5344 reportParseError("unexpected token, expected end of statement");
5348 return false; // parseDirectiveModule has finished successfully.
5349 } else if (Option == "fp") {
5350 return parseDirectiveModuleFP();
5351 } else if (Option == "softfloat") {
5352 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5354 // Synchronize the ABI Flags information with the FeatureBits information we
5356 getTargetStreamer().updateABIInfo(*this);
5358 // If printing assembly, use the recently updated ABI Flags information.
5359 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5361 getTargetStreamer().emitDirectiveModuleSoftFloat();
5363 // If this is not the end of the statement, report an error.
5364 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5365 reportParseError("unexpected token, expected end of statement");
5369 return false; // parseDirectiveModule has finished successfully.
5370 } else if (Option == "hardfloat") {
5371 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5373 // Synchronize the ABI Flags information with the FeatureBits information we
5375 getTargetStreamer().updateABIInfo(*this);
5377 // If printing assembly, use the recently updated ABI Flags information.
5378 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5380 getTargetStreamer().emitDirectiveModuleHardFloat();
5382 // If this is not the end of the statement, report an error.
5383 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5384 reportParseError("unexpected token, expected end of statement");
5388 return false; // parseDirectiveModule has finished successfully.
5390 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5394 /// parseDirectiveModuleFP
5398 bool MipsAsmParser::parseDirectiveModuleFP() {
5399 MCAsmParser &Parser = getParser();
5400 MCAsmLexer &Lexer = getLexer();
5402 if (Lexer.isNot(AsmToken::Equal)) {
5403 reportParseError("unexpected token, expected equals sign '='");
5406 Parser.Lex(); // Eat '=' token.
5408 MipsABIFlagsSection::FpABIKind FpABI;
5409 if (!parseFpABIValue(FpABI, ".module"))
5412 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5413 reportParseError("unexpected token, expected end of statement");
5417 // Synchronize the abiflags information with the FeatureBits information we
5419 getTargetStreamer().updateABIInfo(*this);
5421 // If printing assembly, use the recently updated abiflags information.
5422 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5423 // emitted at the end).
5424 getTargetStreamer().emitDirectiveModuleFP();
5426 Parser.Lex(); // Consume the EndOfStatement.
5430 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5431 StringRef Directive) {
5432 MCAsmParser &Parser = getParser();
5433 MCAsmLexer &Lexer = getLexer();
5434 bool ModuleLevelOptions = Directive == ".module";
5436 if (Lexer.is(AsmToken::Identifier)) {
5437 StringRef Value = Parser.getTok().getString();
5440 if (Value != "xx") {
5441 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5446 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5450 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5451 if (ModuleLevelOptions) {
5452 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5453 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5455 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5456 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5461 if (Lexer.is(AsmToken::Integer)) {
5462 unsigned Value = Parser.getTok().getIntVal();
5465 if (Value != 32 && Value != 64) {
5466 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5472 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5476 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5477 if (ModuleLevelOptions) {
5478 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5479 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5481 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5482 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5485 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5486 if (ModuleLevelOptions) {
5487 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5488 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5490 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5491 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5501 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5502 MCAsmParser &Parser = getParser();
5503 StringRef IDVal = DirectiveID.getString();
5505 if (IDVal == ".cpload")
5506 return parseDirectiveCpLoad(DirectiveID.getLoc());
5507 if (IDVal == ".cprestore")
5508 return parseDirectiveCpRestore(DirectiveID.getLoc());
5509 if (IDVal == ".dword") {
5510 parseDataDirective(8, DirectiveID.getLoc());
5513 if (IDVal == ".ent") {
5514 StringRef SymbolName;
5516 if (Parser.parseIdentifier(SymbolName)) {
5517 reportParseError("expected identifier after .ent");
5521 // There's an undocumented extension that allows an integer to
5522 // follow the name of the procedure which AFAICS is ignored by GAS.
5523 // Example: .ent foo,2
5524 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5525 if (getLexer().isNot(AsmToken::Comma)) {
5526 // Even though we accept this undocumented extension for compatibility
5527 // reasons, the additional integer argument does not actually change
5528 // the behaviour of the '.ent' directive, so we would like to discourage
5529 // its use. We do this by not referring to the extended version in
5530 // error messages which are not directly related to its use.
5531 reportParseError("unexpected token, expected end of statement");
5534 Parser.Lex(); // Eat the comma.
5535 const MCExpr *DummyNumber;
5536 int64_t DummyNumberVal;
5537 // If the user was explicitly trying to use the extended version,
5538 // we still give helpful extension-related error messages.
5539 if (Parser.parseExpression(DummyNumber)) {
5540 reportParseError("expected number after comma");
5543 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5544 reportParseError("expected an absolute expression after comma");
5549 // If this is not the end of the statement, report an error.
5550 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5551 reportParseError("unexpected token, expected end of statement");
5555 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5557 getTargetStreamer().emitDirectiveEnt(*Sym);
5559 IsCpRestoreSet = false;
5563 if (IDVal == ".end") {
5564 StringRef SymbolName;
5566 if (Parser.parseIdentifier(SymbolName)) {
5567 reportParseError("expected identifier after .end");
5571 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5572 reportParseError("unexpected token, expected end of statement");
5576 if (CurrentFn == nullptr) {
5577 reportParseError(".end used without .ent");
5581 if ((SymbolName != CurrentFn->getName())) {
5582 reportParseError(".end symbol does not match .ent symbol");
5586 getTargetStreamer().emitDirectiveEnd(SymbolName);
5587 CurrentFn = nullptr;
5588 IsCpRestoreSet = false;
5592 if (IDVal == ".frame") {
5593 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5594 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5595 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5596 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5597 reportParseError("expected stack register");
5601 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5602 if (!StackRegOpnd.isGPRAsmReg()) {
5603 reportParseError(StackRegOpnd.getStartLoc(),
5604 "expected general purpose register");
5607 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5609 if (Parser.getTok().is(AsmToken::Comma))
5612 reportParseError("unexpected token, expected comma");
5616 // Parse the frame size.
5617 const MCExpr *FrameSize;
5618 int64_t FrameSizeVal;
5620 if (Parser.parseExpression(FrameSize)) {
5621 reportParseError("expected frame size value");
5625 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5626 reportParseError("frame size not an absolute expression");
5630 if (Parser.getTok().is(AsmToken::Comma))
5633 reportParseError("unexpected token, expected comma");
5637 // Parse the return register.
5639 ResTy = parseAnyRegister(TmpReg);
5640 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5641 reportParseError("expected return register");
5645 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5646 if (!ReturnRegOpnd.isGPRAsmReg()) {
5647 reportParseError(ReturnRegOpnd.getStartLoc(),
5648 "expected general purpose register");
5652 // If this is not the end of the statement, report an error.
5653 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5654 reportParseError("unexpected token, expected end of statement");
5658 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5659 ReturnRegOpnd.getGPR32Reg());
5660 IsCpRestoreSet = false;
5664 if (IDVal == ".set") {
5665 return parseDirectiveSet();
5668 if (IDVal == ".mask" || IDVal == ".fmask") {
5669 // .mask bitmask, frame_offset
5670 // bitmask: One bit for each register used.
5671 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5672 // first register is expected to be saved.
5674 // .mask 0x80000000, -4
5675 // .fmask 0x80000000, -4
5678 // Parse the bitmask
5679 const MCExpr *BitMask;
5682 if (Parser.parseExpression(BitMask)) {
5683 reportParseError("expected bitmask value");
5687 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5688 reportParseError("bitmask not an absolute expression");
5692 if (Parser.getTok().is(AsmToken::Comma))
5695 reportParseError("unexpected token, expected comma");
5699 // Parse the frame_offset
5700 const MCExpr *FrameOffset;
5701 int64_t FrameOffsetVal;
5703 if (Parser.parseExpression(FrameOffset)) {
5704 reportParseError("expected frame offset value");
5708 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5709 reportParseError("frame offset not an absolute expression");
5713 // If this is not the end of the statement, report an error.
5714 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5715 reportParseError("unexpected token, expected end of statement");
5719 if (IDVal == ".mask")
5720 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5722 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5726 if (IDVal == ".nan")
5727 return parseDirectiveNaN();
5729 if (IDVal == ".gpword") {
5730 parseDirectiveGpWord();
5734 if (IDVal == ".gpdword") {
5735 parseDirectiveGpDWord();
5739 if (IDVal == ".word") {
5740 parseDataDirective(4, DirectiveID.getLoc());
5744 if (IDVal == ".option")
5745 return parseDirectiveOption();
5747 if (IDVal == ".abicalls") {
5748 getTargetStreamer().emitDirectiveAbiCalls();
5749 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5750 Error(Parser.getTok().getLoc(),
5751 "unexpected token, expected end of statement");
5753 Parser.eatToEndOfStatement();
5758 if (IDVal == ".cpsetup")
5759 return parseDirectiveCPSetup();
5761 if (IDVal == ".cpreturn")
5762 return parseDirectiveCPReturn();
5764 if (IDVal == ".module")
5765 return parseDirectiveModule();
5767 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5768 return parseInternalDirectiveReallowModule();
5770 if (IDVal == ".insn")
5771 return parseInsnDirective();
5776 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5777 // If this is not the end of the statement, report an error.
5778 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5779 reportParseError("unexpected token, expected end of statement");
5783 getTargetStreamer().reallowModuleDirective();
5785 getParser().Lex(); // Eat EndOfStatement token.
5789 extern "C" void LLVMInitializeMipsAsmParser() {
5790 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5791 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5792 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5793 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5796 #define GET_REGISTER_MATCHER
5797 #define GET_MATCHER_IMPLEMENTATION
5798 #include "MipsGenAsmMatcher.inc"