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 template <unsigned Bits>
898 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
899 assert(N == 1 && "Invalid number of operands!");
900 uint64_t Imm = getConstantImm() & ((1 << Bits) - 1);
901 Inst.addOperand(MCOperand::createImm(Imm));
904 void addImmOperands(MCInst &Inst, unsigned N) const {
905 assert(N == 1 && "Invalid number of operands!");
906 const MCExpr *Expr = getImm();
910 void addMemOperands(MCInst &Inst, unsigned N) const {
911 assert(N == 2 && "Invalid number of operands!");
913 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
914 ? getMemBase()->getGPR64Reg()
915 : getMemBase()->getGPR32Reg()));
917 const MCExpr *Expr = getMemOff();
921 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
922 assert(N == 2 && "Invalid number of operands!");
924 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
926 const MCExpr *Expr = getMemOff();
930 void addRegListOperands(MCInst &Inst, unsigned N) const {
931 assert(N == 1 && "Invalid number of operands!");
933 for (auto RegNo : getRegList())
934 Inst.addOperand(MCOperand::createReg(RegNo));
937 void addRegPairOperands(MCInst &Inst, unsigned N) const {
938 assert(N == 2 && "Invalid number of operands!");
939 unsigned RegNo = getRegPair();
940 Inst.addOperand(MCOperand::createReg(RegNo++));
941 Inst.addOperand(MCOperand::createReg(RegNo));
944 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
945 assert(N == 2 && "Invalid number of operands!");
946 for (auto RegNo : getRegList())
947 Inst.addOperand(MCOperand::createReg(RegNo));
950 bool isReg() const override {
951 // As a special case until we sort out the definition of div/divu, pretend
952 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
953 if (isGPRAsmReg() && RegIdx.Index == 0)
956 return Kind == k_PhysRegister;
958 bool isRegIdx() const { return Kind == k_RegisterIndex; }
959 bool isImm() const override { return Kind == k_Immediate; }
960 bool isConstantImm() const {
961 return isImm() && dyn_cast<MCConstantExpr>(getImm());
963 bool isConstantImmz() const {
964 return isConstantImm() && getConstantImm() == 0;
966 template <unsigned Bits> bool isUImm() const {
967 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
969 bool isToken() const override {
970 // Note: It's not possible to pretend that other operand kinds are tokens.
971 // The matcher emitter checks tokens first.
972 return Kind == k_Token;
974 bool isMem() const override { return Kind == k_Memory; }
975 bool isConstantMemOff() const {
976 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
978 template <unsigned Bits> bool isMemWithSimmOffset() const {
979 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
980 && getMemBase()->isGPRAsmReg();
982 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
983 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
984 getMemBase()->isGPRAsmReg();
986 bool isMemWithGRPMM16Base() const {
987 return isMem() && getMemBase()->isMM16AsmReg();
989 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
990 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
991 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
993 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
994 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
995 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
996 && (getMemBase()->getGPR32Reg() == Mips::SP);
998 bool isUImm5Lsl2() const {
999 return (isImm() && isConstantImm() && isShiftedUInt<5, 2>(getConstantImm()));
1001 bool isRegList16() const {
1005 int Size = RegList.List->size();
1006 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
1007 RegList.List->back() != Mips::RA)
1010 int PrevReg = *RegList.List->begin();
1011 for (int i = 1; i < Size - 1; i++) {
1012 int Reg = (*(RegList.List))[i];
1013 if ( Reg != PrevReg + 1)
1020 bool isInvNum() const { return Kind == k_Immediate; }
1021 bool isLSAImm() const {
1022 if (!isConstantImm())
1024 int64_t Val = getConstantImm();
1025 return 1 <= Val && Val <= 4;
1027 bool isRegList() const { return Kind == k_RegList; }
1028 bool isMovePRegPair() const {
1029 if (Kind != k_RegList || RegList.List->size() != 2)
1032 unsigned R0 = RegList.List->front();
1033 unsigned R1 = RegList.List->back();
1035 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1036 (R0 == Mips::A1 && R1 == Mips::A3) ||
1037 (R0 == Mips::A2 && R1 == Mips::A3) ||
1038 (R0 == Mips::A0 && R1 == Mips::S5) ||
1039 (R0 == Mips::A0 && R1 == Mips::S6) ||
1040 (R0 == Mips::A0 && R1 == Mips::A1) ||
1041 (R0 == Mips::A0 && R1 == Mips::A2) ||
1042 (R0 == Mips::A0 && R1 == Mips::A3))
1048 StringRef getToken() const {
1049 assert(Kind == k_Token && "Invalid access!");
1050 return StringRef(Tok.Data, Tok.Length);
1052 bool isRegPair() const { return Kind == k_RegPair; }
1054 unsigned getReg() const override {
1055 // As a special case until we sort out the definition of div/divu, pretend
1056 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1057 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1058 RegIdx.Kind & RegKind_GPR)
1059 return getGPR32Reg(); // FIXME: GPR64 too
1061 assert(Kind == k_PhysRegister && "Invalid access!");
1065 const MCExpr *getImm() const {
1066 assert((Kind == k_Immediate) && "Invalid access!");
1070 int64_t getConstantImm() const {
1071 const MCExpr *Val = getImm();
1072 return static_cast<const MCConstantExpr *>(Val)->getValue();
1075 MipsOperand *getMemBase() const {
1076 assert((Kind == k_Memory) && "Invalid access!");
1080 const MCExpr *getMemOff() const {
1081 assert((Kind == k_Memory) && "Invalid access!");
1085 int64_t getConstantMemOff() const {
1086 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1089 const SmallVectorImpl<unsigned> &getRegList() const {
1090 assert((Kind == k_RegList) && "Invalid access!");
1091 return *(RegList.List);
1094 unsigned getRegPair() const {
1095 assert((Kind == k_RegPair) && "Invalid access!");
1096 return RegIdx.Index;
1099 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1100 MipsAsmParser &Parser) {
1101 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1102 Op->Tok.Data = Str.data();
1103 Op->Tok.Length = Str.size();
1109 /// Create a numeric register (e.g. $1). The exact register remains
1110 /// unresolved until an instruction successfully matches
1111 static std::unique_ptr<MipsOperand>
1112 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1113 SMLoc E, MipsAsmParser &Parser) {
1114 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1115 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1118 /// Create a register that is definitely a GPR.
1119 /// This is typically only used for named registers such as $gp.
1120 static std::unique_ptr<MipsOperand>
1121 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1122 MipsAsmParser &Parser) {
1123 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1126 /// Create a register that is definitely a FGR.
1127 /// This is typically only used for named registers such as $f0.
1128 static std::unique_ptr<MipsOperand>
1129 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1130 MipsAsmParser &Parser) {
1131 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1134 /// Create a register that is definitely a HWReg.
1135 /// This is typically only used for named registers such as $hwr_cpunum.
1136 static std::unique_ptr<MipsOperand>
1137 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1138 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1139 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1142 /// Create a register that is definitely an FCC.
1143 /// This is typically only used for named registers such as $fcc0.
1144 static std::unique_ptr<MipsOperand>
1145 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1146 MipsAsmParser &Parser) {
1147 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1150 /// Create a register that is definitely an ACC.
1151 /// This is typically only used for named registers such as $ac0.
1152 static std::unique_ptr<MipsOperand>
1153 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1154 MipsAsmParser &Parser) {
1155 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1158 /// Create a register that is definitely an MSA128.
1159 /// This is typically only used for named registers such as $w0.
1160 static std::unique_ptr<MipsOperand>
1161 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1162 SMLoc E, MipsAsmParser &Parser) {
1163 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1166 /// Create a register that is definitely an MSACtrl.
1167 /// This is typically only used for named registers such as $msaaccess.
1168 static std::unique_ptr<MipsOperand>
1169 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1170 SMLoc E, MipsAsmParser &Parser) {
1171 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1174 static std::unique_ptr<MipsOperand>
1175 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1176 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1183 static std::unique_ptr<MipsOperand>
1184 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1185 SMLoc E, MipsAsmParser &Parser) {
1186 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1187 Op->Mem.Base = Base.release();
1194 static std::unique_ptr<MipsOperand>
1195 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1196 MipsAsmParser &Parser) {
1197 assert (Regs.size() > 0 && "Empty list not allowed");
1199 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1200 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1201 Op->StartLoc = StartLoc;
1202 Op->EndLoc = EndLoc;
1206 static std::unique_ptr<MipsOperand>
1207 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1208 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1209 Op->RegIdx.Index = RegNo;
1215 bool isGPRAsmReg() const {
1216 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1218 bool isMM16AsmReg() const {
1219 if (!(isRegIdx() && RegIdx.Kind))
1221 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1222 || RegIdx.Index == 16 || RegIdx.Index == 17);
1224 bool isMM16AsmRegZero() const {
1225 if (!(isRegIdx() && RegIdx.Kind))
1227 return (RegIdx.Index == 0 ||
1228 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1229 RegIdx.Index == 17);
1231 bool isMM16AsmRegMoveP() const {
1232 if (!(isRegIdx() && RegIdx.Kind))
1234 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1235 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1237 bool isFGRAsmReg() const {
1238 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1239 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1241 bool isHWRegsAsmReg() const {
1242 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1244 bool isCCRAsmReg() const {
1245 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1247 bool isFCCAsmReg() const {
1248 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1250 if (!AsmParser.hasEightFccRegisters())
1251 return RegIdx.Index == 0;
1252 return RegIdx.Index <= 7;
1254 bool isACCAsmReg() const {
1255 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1257 bool isCOP0AsmReg() const {
1258 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1260 bool isCOP2AsmReg() const {
1261 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1263 bool isCOP3AsmReg() const {
1264 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1266 bool isMSA128AsmReg() const {
1267 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1269 bool isMSACtrlAsmReg() const {
1270 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1273 /// getStartLoc - Get the location of the first token of this operand.
1274 SMLoc getStartLoc() const override { return StartLoc; }
1275 /// getEndLoc - Get the location of the last token of this operand.
1276 SMLoc getEndLoc() const override { return EndLoc; }
1278 virtual ~MipsOperand() {
1286 delete RegList.List;
1287 case k_PhysRegister:
1288 case k_RegisterIndex:
1295 void print(raw_ostream &OS) const override {
1304 Mem.Base->print(OS);
1309 case k_PhysRegister:
1310 OS << "PhysReg<" << PhysReg.Num << ">";
1312 case k_RegisterIndex:
1313 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1320 for (auto Reg : (*RegList.List))
1325 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1329 }; // class MipsOperand
1333 extern const MCInstrDesc MipsInsts[];
1335 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1336 return MipsInsts[Opcode];
1339 static bool hasShortDelaySlot(unsigned Opcode) {
1342 case Mips::JALRS_MM:
1343 case Mips::JALRS16_MM:
1344 case Mips::BGEZALS_MM:
1345 case Mips::BLTZALS_MM:
1352 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1353 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1354 return &SRExpr->getSymbol();
1357 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1358 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1359 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1370 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1371 return getSingleMCSymbol(UExpr->getSubExpr());
1376 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1377 if (isa<MCSymbolRefExpr>(Expr))
1380 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1381 return countMCSymbolRefExpr(BExpr->getLHS()) +
1382 countMCSymbolRefExpr(BExpr->getRHS());
1384 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1385 return countMCSymbolRefExpr(UExpr->getSubExpr());
1391 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1392 SmallVectorImpl<MCInst> &Instructions) {
1394 tmpInst.setOpcode(Opcode);
1395 tmpInst.addOperand(MCOperand::createReg(Reg0));
1396 tmpInst.addOperand(Op1);
1397 tmpInst.setLoc(IDLoc);
1398 Instructions.push_back(tmpInst);
1401 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1402 SmallVectorImpl<MCInst> &Instructions) {
1403 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1406 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1407 SmallVectorImpl<MCInst> &Instructions) {
1408 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1411 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1412 SmallVectorImpl<MCInst> &Instructions) {
1414 tmpInst.setOpcode(Opcode);
1415 tmpInst.addOperand(MCOperand::createImm(Imm1));
1416 tmpInst.addOperand(MCOperand::createImm(Imm2));
1417 tmpInst.setLoc(IDLoc);
1418 Instructions.push_back(tmpInst);
1421 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1422 SmallVectorImpl<MCInst> &Instructions) {
1424 tmpInst.setOpcode(Opcode);
1425 tmpInst.addOperand(MCOperand::createReg(Reg0));
1426 tmpInst.setLoc(IDLoc);
1427 Instructions.push_back(tmpInst);
1430 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1431 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1433 tmpInst.setOpcode(Opcode);
1434 tmpInst.addOperand(MCOperand::createReg(Reg0));
1435 tmpInst.addOperand(MCOperand::createReg(Reg1));
1436 tmpInst.addOperand(Op2);
1437 tmpInst.setLoc(IDLoc);
1438 Instructions.push_back(tmpInst);
1441 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1442 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1443 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1447 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1448 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1449 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1453 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1454 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1455 if (ShiftAmount >= 32) {
1456 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1461 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1463 } // end anonymous namespace.
1465 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1466 SmallVectorImpl<MCInst> &Instructions) {
1467 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1468 bool ExpandedJalSym = false;
1472 if (MCID.isBranch() || MCID.isCall()) {
1473 const unsigned Opcode = Inst.getOpcode();
1483 assert(hasCnMips() && "instruction only valid for octeon cpus");
1490 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1491 Offset = Inst.getOperand(2);
1492 if (!Offset.isImm())
1493 break; // We'll deal with this situation later on when applying fixups.
1494 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1495 return Error(IDLoc, "branch target out of range");
1496 if (OffsetToAlignment(Offset.getImm(),
1497 1LL << (inMicroMipsMode() ? 1 : 2)))
1498 return Error(IDLoc, "branch to misaligned address");
1512 case Mips::BGEZAL_MM:
1513 case Mips::BLTZAL_MM:
1516 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1517 Offset = Inst.getOperand(1);
1518 if (!Offset.isImm())
1519 break; // We'll deal with this situation later on when applying fixups.
1520 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1521 return Error(IDLoc, "branch target out of range");
1522 if (OffsetToAlignment(Offset.getImm(),
1523 1LL << (inMicroMipsMode() ? 1 : 2)))
1524 return Error(IDLoc, "branch to misaligned address");
1526 case Mips::BEQZ16_MM:
1527 case Mips::BEQZC16_MMR6:
1528 case Mips::BNEZ16_MM:
1529 case Mips::BNEZC16_MMR6:
1530 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1531 Offset = Inst.getOperand(1);
1532 if (!Offset.isImm())
1533 break; // We'll deal with this situation later on when applying fixups.
1534 if (!isInt<8>(Offset.getImm()))
1535 return Error(IDLoc, "branch target out of range");
1536 if (OffsetToAlignment(Offset.getImm(), 2LL))
1537 return Error(IDLoc, "branch to misaligned address");
1542 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1543 // We still accept it but it is a normal nop.
1544 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1545 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1546 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1551 const unsigned Opcode = Inst.getOpcode();
1563 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1564 // The offset is handled above
1565 Opnd = Inst.getOperand(1);
1567 return Error(IDLoc, "expected immediate operand kind");
1568 Imm = Opnd.getImm();
1569 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1570 Opcode == Mips::BBIT1 ? 63 : 31))
1571 return Error(IDLoc, "immediate operand value out of range");
1573 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1575 Inst.getOperand(1).setImm(Imm - 32);
1583 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1585 Opnd = Inst.getOperand(3);
1587 return Error(IDLoc, "expected immediate operand kind");
1588 Imm = Opnd.getImm();
1589 if (Imm < 0 || Imm > 31)
1590 return Error(IDLoc, "immediate operand value out of range");
1592 Opnd = Inst.getOperand(2);
1594 return Error(IDLoc, "expected immediate operand kind");
1595 Imm = Opnd.getImm();
1596 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1597 Opcode == Mips::EXTS ? 63 : 31))
1598 return Error(IDLoc, "immediate operand value out of range");
1600 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1601 Inst.getOperand(2).setImm(Imm - 32);
1607 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1608 Opnd = Inst.getOperand(2);
1610 return Error(IDLoc, "expected immediate operand kind");
1611 Imm = Opnd.getImm();
1612 if (!isInt<10>(Imm))
1613 return Error(IDLoc, "immediate operand value out of range");
1618 // This expansion is not in a function called by tryExpandInstruction()
1619 // because the pseudo-instruction doesn't have a distinct opcode.
1620 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1622 warnIfNoMacro(IDLoc);
1624 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1626 // We can do this expansion if there's only 1 symbol in the argument
1628 if (countMCSymbolRefExpr(JalExpr) > 1)
1629 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1631 // FIXME: This is checking the expression can be handled by the later stages
1632 // of the assembler. We ought to leave it to those later stages but
1633 // we can't do that until we stop evaluateRelocExpr() rewriting the
1634 // expressions into non-equivalent forms.
1635 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1637 // FIXME: Add support for label+offset operands (currently causes an error).
1638 // FIXME: Add support for forward-declared local symbols.
1639 // FIXME: Add expansion for when the LargeGOT option is enabled.
1640 if (JalSym->isInSection() || JalSym->isTemporary()) {
1642 // If it's a local symbol and the O32 ABI is being used, we expand to:
1644 // R_(MICRO)MIPS_GOT16 label
1645 // addiu $25, $25, 0
1646 // R_(MICRO)MIPS_LO16 label
1648 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1649 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1651 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1652 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1653 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1654 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1655 } else if (isABI_N32() || isABI_N64()) {
1656 // If it's a local symbol and the N32/N64 ABIs are being used,
1658 // lw/ld $25, 0($gp)
1659 // R_(MICRO)MIPS_GOT_DISP label
1661 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1663 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1664 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1667 // If it's an external/weak symbol, we expand to:
1668 // lw/ld $25, 0($gp)
1669 // R_(MICRO)MIPS_CALL16 label
1671 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1673 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1674 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1678 if (IsCpRestoreSet && inMicroMipsMode())
1679 JalrInst.setOpcode(Mips::JALRS_MM);
1681 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1682 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1683 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1685 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1686 // This relocation is supposed to be an optimization hint for the linker
1687 // and is not necessary for correctness.
1690 ExpandedJalSym = true;
1693 if (MCID.mayLoad() || MCID.mayStore()) {
1694 // Check the offset of memory operand, if it is a symbol
1695 // reference or immediate we may have to expand instructions.
1696 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1697 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1698 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1699 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1700 MCOperand &Op = Inst.getOperand(i);
1702 int MemOffset = Op.getImm();
1703 if (MemOffset < -32768 || MemOffset > 32767) {
1704 // Offset can't exceed 16bit value.
1705 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1708 } else if (Op.isExpr()) {
1709 const MCExpr *Expr = Op.getExpr();
1710 if (Expr->getKind() == MCExpr::SymbolRef) {
1711 const MCSymbolRefExpr *SR =
1712 static_cast<const MCSymbolRefExpr *>(Expr);
1713 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1715 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1718 } else if (!isEvaluated(Expr)) {
1719 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1727 if (inMicroMipsMode()) {
1728 if (MCID.mayLoad()) {
1729 // Try to create 16-bit GP relative load instruction.
1730 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1731 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1732 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1733 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1734 MCOperand &Op = Inst.getOperand(i);
1736 int MemOffset = Op.getImm();
1737 MCOperand &DstReg = Inst.getOperand(0);
1738 MCOperand &BaseReg = Inst.getOperand(1);
1739 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1740 getContext().getRegisterInfo()->getRegClass(
1741 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1742 (BaseReg.getReg() == Mips::GP ||
1743 BaseReg.getReg() == Mips::GP_64)) {
1745 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1746 IDLoc, Instructions);
1754 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1759 switch (Inst.getOpcode()) {
1762 case Mips::ADDIUS5_MM:
1763 Opnd = Inst.getOperand(2);
1765 return Error(IDLoc, "expected immediate operand kind");
1766 Imm = Opnd.getImm();
1767 if (Imm < -8 || Imm > 7)
1768 return Error(IDLoc, "immediate operand value out of range");
1770 case Mips::ADDIUSP_MM:
1771 Opnd = Inst.getOperand(0);
1773 return Error(IDLoc, "expected immediate operand kind");
1774 Imm = Opnd.getImm();
1775 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1777 return Error(IDLoc, "immediate operand value out of range");
1779 case Mips::SLL16_MM:
1780 case Mips::SRL16_MM:
1781 Opnd = Inst.getOperand(2);
1783 return Error(IDLoc, "expected immediate operand kind");
1784 Imm = Opnd.getImm();
1785 if (Imm < 1 || Imm > 8)
1786 return Error(IDLoc, "immediate operand value out of range");
1789 Opnd = Inst.getOperand(1);
1791 return Error(IDLoc, "expected immediate operand kind");
1792 Imm = Opnd.getImm();
1793 if (Imm < -1 || Imm > 126)
1794 return Error(IDLoc, "immediate operand value out of range");
1796 case Mips::ADDIUR2_MM:
1797 Opnd = Inst.getOperand(2);
1799 return Error(IDLoc, "expected immediate operand kind");
1800 Imm = Opnd.getImm();
1801 if (!(Imm == 1 || Imm == -1 ||
1802 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1803 return Error(IDLoc, "immediate operand value out of range");
1805 case Mips::ADDIUR1SP_MM:
1806 Opnd = Inst.getOperand(1);
1808 return Error(IDLoc, "expected immediate operand kind");
1809 Imm = Opnd.getImm();
1810 if (OffsetToAlignment(Imm, 4LL))
1811 return Error(IDLoc, "misaligned immediate operand value");
1812 if (Imm < 0 || Imm > 255)
1813 return Error(IDLoc, "immediate operand value out of range");
1815 case Mips::ANDI16_MM:
1816 Opnd = Inst.getOperand(2);
1818 return Error(IDLoc, "expected immediate operand kind");
1819 Imm = Opnd.getImm();
1820 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1821 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1822 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1823 return Error(IDLoc, "immediate operand value out of range");
1825 case Mips::LBU16_MM:
1826 Opnd = Inst.getOperand(2);
1828 return Error(IDLoc, "expected immediate operand kind");
1829 Imm = Opnd.getImm();
1830 if (Imm < -1 || Imm > 14)
1831 return Error(IDLoc, "immediate operand value out of range");
1840 Opnd = Inst.getOperand(2);
1842 return Error(IDLoc, "expected immediate operand kind");
1843 Imm = Opnd.getImm();
1844 if (Imm < 0 || Imm > 15)
1845 return Error(IDLoc, "immediate operand value out of range");
1847 case Mips::LHU16_MM:
1849 Opnd = Inst.getOperand(2);
1851 return Error(IDLoc, "expected immediate operand kind");
1852 Imm = Opnd.getImm();
1853 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1854 return Error(IDLoc, "immediate operand value out of range");
1858 Opnd = Inst.getOperand(2);
1860 return Error(IDLoc, "expected immediate operand kind");
1861 Imm = Opnd.getImm();
1862 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1863 return Error(IDLoc, "immediate operand value out of range");
1865 case Mips::PREFX_MM:
1868 Opnd = Inst.getOperand(2);
1870 return Error(IDLoc, "expected immediate operand kind");
1871 Imm = Opnd.getImm();
1872 if (!isUInt<5>(Imm))
1873 return Error(IDLoc, "immediate operand value out of range");
1875 case Mips::ADDIUPC_MM:
1876 MCOperand Opnd = Inst.getOperand(1);
1878 return Error(IDLoc, "expected immediate operand kind");
1879 int Imm = Opnd.getImm();
1880 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1881 return Error(IDLoc, "immediate operand value out of range");
1886 MacroExpanderResultTy ExpandResult =
1887 tryExpandInstruction(Inst, IDLoc, Instructions);
1888 switch (ExpandResult) {
1890 Instructions.push_back(Inst);
1898 // If this instruction has a delay slot and .set reorder is active,
1899 // emit a NOP after it.
1900 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1901 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1903 if ((Inst.getOpcode() == Mips::JalOneReg ||
1904 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1905 isPicAndNotNxxAbi()) {
1906 if (IsCpRestoreSet) {
1907 // We need a NOP between the JALR and the LW:
1908 // If .set reorder has been used, we've already emitted a NOP.
1909 // If .set noreorder has been used, we need to emit a NOP at this point.
1910 if (!AssemblerOptions.back()->isReorder())
1911 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1913 // Load the $gp from the stack.
1914 SmallVector<MCInst, 3> LoadInsts;
1915 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1918 for (const MCInst &Inst : LoadInsts)
1919 Instructions.push_back(Inst);
1922 Warning(IDLoc, "no .cprestore used in PIC mode");
1928 MipsAsmParser::MacroExpanderResultTy
1929 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
1930 SmallVectorImpl<MCInst> &Instructions) {
1931 switch (Inst.getOpcode()) {
1933 return MER_NotAMacro;
1934 case Mips::LoadImm32:
1935 return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
1937 case Mips::LoadImm64:
1938 return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
1940 case Mips::LoadAddrImm32:
1941 case Mips::LoadAddrImm64:
1942 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1943 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1944 "expected immediate operand kind");
1946 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
1948 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1952 case Mips::LoadAddrReg32:
1953 case Mips::LoadAddrReg64:
1954 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1955 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1956 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1957 "expected immediate operand kind");
1959 return expandLoadAddress(Inst.getOperand(0).getReg(),
1960 Inst.getOperand(1).getReg(), Inst.getOperand(2),
1961 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
1965 case Mips::B_MM_Pseudo:
1966 case Mips::B_MMR6_Pseudo:
1967 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
1971 return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
1973 case Mips::JalOneReg:
1974 case Mips::JalTwoReg:
1975 return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
1979 return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
1996 case Mips::BLTImmMacro:
1997 case Mips::BLEImmMacro:
1998 case Mips::BGEImmMacro:
1999 case Mips::BGTImmMacro:
2000 case Mips::BLTUImmMacro:
2001 case Mips::BLEUImmMacro:
2002 case Mips::BGEUImmMacro:
2003 case Mips::BGTUImmMacro:
2004 case Mips::BLTLImmMacro:
2005 case Mips::BLELImmMacro:
2006 case Mips::BGELImmMacro:
2007 case Mips::BGTLImmMacro:
2008 case Mips::BLTULImmMacro:
2009 case Mips::BLEULImmMacro:
2010 case Mips::BGEULImmMacro:
2011 case Mips::BGTULImmMacro:
2012 return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2014 case Mips::SDivMacro:
2015 return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2017 case Mips::DSDivMacro:
2018 return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2020 case Mips::UDivMacro:
2021 return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2023 case Mips::DUDivMacro:
2024 return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2027 return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2029 return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2031 return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2033 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2039 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2040 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2041 int64_t ImmValue = Inst.getOperand(2).getImm();
2042 if (isInt<16>(ImmValue))
2043 return MER_NotAMacro;
2044 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2047 return MER_NotAMacro;
2051 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2052 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2053 int64_t ImmValue = Inst.getOperand(2).getImm();
2054 if (isUInt<16>(ImmValue))
2055 return MER_NotAMacro;
2056 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2059 return MER_NotAMacro;
2063 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2064 SmallVectorImpl<MCInst> &Instructions) {
2065 // Create a JALR instruction which is going to replace the pseudo-JAL.
2067 JalrInst.setLoc(IDLoc);
2068 const MCOperand FirstRegOp = Inst.getOperand(0);
2069 const unsigned Opcode = Inst.getOpcode();
2071 if (Opcode == Mips::JalOneReg) {
2072 // jal $rs => jalr $rs
2073 if (IsCpRestoreSet && inMicroMipsMode()) {
2074 JalrInst.setOpcode(Mips::JALRS16_MM);
2075 JalrInst.addOperand(FirstRegOp);
2076 } else if (inMicroMipsMode()) {
2077 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2078 JalrInst.addOperand(FirstRegOp);
2080 JalrInst.setOpcode(Mips::JALR);
2081 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2082 JalrInst.addOperand(FirstRegOp);
2084 } else if (Opcode == Mips::JalTwoReg) {
2085 // jal $rd, $rs => jalr $rd, $rs
2086 if (IsCpRestoreSet && inMicroMipsMode())
2087 JalrInst.setOpcode(Mips::JALRS_MM);
2089 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2090 JalrInst.addOperand(FirstRegOp);
2091 const MCOperand SecondRegOp = Inst.getOperand(1);
2092 JalrInst.addOperand(SecondRegOp);
2094 Instructions.push_back(JalrInst);
2096 // If .set reorder is active and branch instruction has a delay slot,
2097 // emit a NOP after it.
2098 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2099 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2100 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2106 /// Can the value be represented by a unsigned N-bit value and a shift left?
2107 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2108 unsigned BitNum = findFirstSet(x);
2110 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2113 /// Load (or add) an immediate into a register.
2115 /// @param ImmValue The immediate to load.
2116 /// @param DstReg The register that will hold the immediate.
2117 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2118 /// for a simple initialization.
2119 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2120 /// @param IsAddress True if the immediate represents an address. False if it
2122 /// @param IDLoc Location of the immediate in the source file.
2123 /// @param Instructions The instructions emitted by this expansion.
2124 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2125 unsigned SrcReg, bool Is32BitImm,
2126 bool IsAddress, SMLoc IDLoc,
2127 SmallVectorImpl<MCInst> &Instructions) {
2128 if (!Is32BitImm && !isGP64bit()) {
2129 Error(IDLoc, "instruction requires a 64-bit architecture");
2134 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2135 // Sign extend up to 64-bit so that the predicates match the hardware
2136 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2138 ImmValue = SignExtend64<32>(ImmValue);
2140 Error(IDLoc, "instruction requires a 32-bit immediate");
2145 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2146 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2148 bool UseSrcReg = false;
2149 if (SrcReg != Mips::NoRegister)
2152 unsigned TmpReg = DstReg;
2153 if (UseSrcReg && (DstReg == SrcReg)) {
2154 // At this point we need AT to perform the expansions and we exit if it is
2156 unsigned ATReg = getATReg(IDLoc);
2162 if (isInt<16>(ImmValue)) {
2166 // This doesn't quite follow the usual ABI expectations for N32 but matches
2167 // traditional assembler behaviour. N32 would normally use addiu for both
2168 // integers and addresses.
2169 if (IsAddress && !Is32BitImm) {
2170 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2174 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2178 if (isUInt<16>(ImmValue)) {
2179 unsigned TmpReg = DstReg;
2180 if (SrcReg == DstReg) {
2181 TmpReg = getATReg(IDLoc);
2186 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2188 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2192 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2193 warnIfNoMacro(IDLoc);
2195 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2196 uint16_t Bits15To0 = ImmValue & 0xffff;
2198 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2199 // Traditional behaviour seems to special case this particular value. It's
2200 // not clear why other masks are handled differently.
2201 if (ImmValue == 0xffffffff) {
2202 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2203 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2205 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2209 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2211 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2212 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2214 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2216 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2220 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2222 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2224 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2228 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2230 Error(IDLoc, "instruction requires a 32-bit immediate");
2234 // Traditionally, these immediates are shifted as little as possible and as
2235 // such we align the most significant bit to bit 15 of our temporary.
2236 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2237 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2238 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2239 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2240 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2241 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2244 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2249 warnIfNoMacro(IDLoc);
2251 // The remaining case is packed with a sequence of dsll and ori with zeros
2252 // being omitted and any neighbouring dsll's being coalesced.
2253 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2255 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2256 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2257 IDLoc, Instructions))
2260 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2261 // skip it and defer the shift to the next chunk.
2262 unsigned ShiftCarriedForwards = 16;
2263 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2264 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2266 if (ImmChunk != 0) {
2267 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2269 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2270 ShiftCarriedForwards = 0;
2273 ShiftCarriedForwards += 16;
2275 ShiftCarriedForwards -= 16;
2277 // Finish any remaining shifts left by trailing zeros.
2278 if (ShiftCarriedForwards)
2279 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2283 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2288 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2289 SmallVectorImpl<MCInst> &Instructions) {
2290 const MCOperand &ImmOp = Inst.getOperand(1);
2291 assert(ImmOp.isImm() && "expected immediate operand kind");
2292 const MCOperand &DstRegOp = Inst.getOperand(0);
2293 assert(DstRegOp.isReg() && "expected register operand kind");
2295 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2296 Is32BitImm, false, IDLoc, Instructions))
2302 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2303 const MCOperand &Offset,
2304 bool Is32BitAddress, SMLoc IDLoc,
2305 SmallVectorImpl<MCInst> &Instructions) {
2306 // la can't produce a usable address when addresses are 64-bit.
2307 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2308 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2309 // We currently can't do this because we depend on the equality
2310 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2311 Error(IDLoc, "la used to load 64-bit address");
2312 // Continue as if we had 'dla' instead.
2313 Is32BitAddress = false;
2316 // dla requires 64-bit addresses.
2317 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2318 Error(IDLoc, "instruction requires a 64-bit architecture");
2322 if (!Offset.isImm())
2323 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2324 Is32BitAddress, IDLoc, Instructions);
2326 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2327 IDLoc, Instructions);
2330 bool MipsAsmParser::loadAndAddSymbolAddress(
2331 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2332 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2333 warnIfNoMacro(IDLoc);
2335 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2336 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2337 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2338 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2339 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2341 bool UseSrcReg = SrcReg != Mips::NoRegister;
2343 // This is the 64-bit symbol address expansion.
2344 if (ABI.ArePtrs64bit() && isGP64bit()) {
2345 // We always need AT for the 64-bit expansion.
2346 // If it is not available we exit.
2347 unsigned ATReg = getATReg(IDLoc);
2351 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2352 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2353 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2354 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2356 if (UseSrcReg && (DstReg == SrcReg)) {
2357 // If $rs is the same as $rd:
2358 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2359 // daddiu $at, $at, %higher(sym)
2360 // dsll $at, $at, 16
2361 // daddiu $at, $at, %hi(sym)
2362 // dsll $at, $at, 16
2363 // daddiu $at, $at, %lo(sym)
2364 // daddu $rd, $at, $rd
2365 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2367 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2368 IDLoc, Instructions);
2369 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2370 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2372 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2373 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2375 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2380 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2381 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2382 // lui $at, %hi(sym)
2383 // daddiu $rd, $rd, %higher(sym)
2384 // daddiu $at, $at, %lo(sym)
2385 // dsll32 $rd, $rd, 0
2386 // daddu $rd, $rd, $at
2387 // (daddu $rd, $rd, $rs)
2388 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2390 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2392 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2393 IDLoc, Instructions);
2394 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2396 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2397 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2399 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2404 // And now, the 32-bit symbol address expansion:
2405 // If $rs is the same as $rd:
2406 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2407 // ori $at, $at, %lo(sym)
2408 // addu $rd, $at, $rd
2409 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2410 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2411 // ori $rd, $rd, %lo(sym)
2412 // (addu $rd, $rd, $rs)
2413 unsigned TmpReg = DstReg;
2414 if (UseSrcReg && (DstReg == SrcReg)) {
2415 // If $rs is the same as $rd, we need to use AT.
2416 // If it is not available we exit.
2417 unsigned ATReg = getATReg(IDLoc);
2423 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2424 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2428 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2430 assert(DstReg == TmpReg);
2435 bool MipsAsmParser::expandUncondBranchMMPseudo(
2436 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2437 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2438 "unexpected number of operands");
2440 MCOperand Offset = Inst.getOperand(0);
2441 if (Offset.isExpr()) {
2443 Inst.setOpcode(Mips::BEQ_MM);
2444 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2445 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2446 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2448 assert(Offset.isImm() && "expected immediate operand kind");
2449 if (isInt<11>(Offset.getImm())) {
2450 // If offset fits into 11 bits then this instruction becomes microMIPS
2451 // 16-bit unconditional branch instruction.
2452 if (inMicroMipsMode())
2453 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2455 if (!isInt<17>(Offset.getImm()))
2456 Error(IDLoc, "branch target out of range");
2457 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2458 Error(IDLoc, "branch to misaligned address");
2460 Inst.setOpcode(Mips::BEQ_MM);
2461 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2462 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2463 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2466 Instructions.push_back(Inst);
2468 // If .set reorder is active and branch instruction has a delay slot,
2469 // emit a NOP after it.
2470 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2471 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2472 createNop(true, IDLoc, Instructions);
2477 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2478 SmallVectorImpl<MCInst> &Instructions) {
2479 const MCOperand &DstRegOp = Inst.getOperand(0);
2480 assert(DstRegOp.isReg() && "expected register operand kind");
2482 const MCOperand &ImmOp = Inst.getOperand(1);
2483 assert(ImmOp.isImm() && "expected immediate operand kind");
2485 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2486 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2488 unsigned OpCode = 0;
2489 switch(Inst.getOpcode()) {
2497 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2501 int64_t ImmValue = ImmOp.getImm();
2503 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2506 warnIfNoMacro(IDLoc);
2508 unsigned ATReg = getATReg(IDLoc);
2512 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2513 IDLoc, Instructions))
2516 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2521 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2522 SmallVectorImpl<MCInst> &Instructions,
2523 bool isLoad, bool isImmOpnd) {
2524 unsigned ImmOffset, HiOffset, LoOffset;
2525 const MCExpr *ExprOffset;
2527 // 1st operand is either the source or destination register.
2528 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2529 unsigned RegOpNum = Inst.getOperand(0).getReg();
2530 // 2nd operand is the base register.
2531 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2532 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2533 // 3rd operand is either an immediate or expression.
2535 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2536 ImmOffset = Inst.getOperand(2).getImm();
2537 LoOffset = ImmOffset & 0x0000ffff;
2538 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2539 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2540 if (LoOffset & 0x8000)
2543 ExprOffset = Inst.getOperand(2).getExpr();
2544 // These are some of the types of expansions we perform here:
2545 // 1) lw $8, sym => lui $8, %hi(sym)
2546 // lw $8, %lo(sym)($8)
2547 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2549 // lw $8, %lo(offset)($9)
2550 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2552 // lw $8, %lo(offset)($at)
2553 // 4) sw $8, sym => lui $at, %hi(sym)
2554 // sw $8, %lo(sym)($at)
2555 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2557 // sw $8, %lo(offset)($at)
2558 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2559 // ldc1 $f0, %lo(sym)($at)
2561 // For load instructions we can use the destination register as a temporary
2562 // if base and dst are different (examples 1 and 2) and if the base register
2563 // is general purpose otherwise we must use $at (example 6) and error if it's
2564 // not available. For stores we must use $at (examples 4 and 5) because we
2565 // must not clobber the source register setting up the offset.
2566 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2567 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2568 unsigned RegClassIDOp0 =
2569 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2570 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2571 (RegClassIDOp0 == Mips::GPR64RegClassID);
2572 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2573 TmpRegNum = RegOpNum;
2575 // At this point we need AT to perform the expansions and we exit if it is
2577 TmpRegNum = getATReg(IDLoc);
2582 emitRX(Mips::LUi, TmpRegNum,
2583 isImmOpnd ? MCOperand::createImm(HiOffset)
2584 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2585 IDLoc, Instructions);
2586 // Add temp register to base.
2587 if (BaseRegNum != Mips::ZERO)
2588 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2589 // And finally, create original instruction with low part
2590 // of offset and new base.
2591 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2593 ? MCOperand::createImm(LoOffset)
2594 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2595 IDLoc, Instructions);
2599 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2600 SmallVectorImpl<MCInst> &Instructions) {
2601 unsigned OpNum = Inst.getNumOperands();
2602 unsigned Opcode = Inst.getOpcode();
2603 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2605 assert (Inst.getOperand(OpNum - 1).isImm() &&
2606 Inst.getOperand(OpNum - 2).isReg() &&
2607 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2609 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2610 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2611 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2612 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2613 // It can be implemented as SWM16 or LWM16 instruction.
2614 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2616 Inst.setOpcode(NewOpcode);
2617 Instructions.push_back(Inst);
2621 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2622 SmallVectorImpl<MCInst> &Instructions) {
2623 bool EmittedNoMacroWarning = false;
2624 unsigned PseudoOpcode = Inst.getOpcode();
2625 unsigned SrcReg = Inst.getOperand(0).getReg();
2626 const MCOperand &TrgOp = Inst.getOperand(1);
2627 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2629 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2630 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2634 TrgReg = TrgOp.getReg();
2635 else if (TrgOp.isImm()) {
2636 warnIfNoMacro(IDLoc);
2637 EmittedNoMacroWarning = true;
2639 TrgReg = getATReg(IDLoc);
2643 switch(PseudoOpcode) {
2645 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2646 case Mips::BLTImmMacro:
2647 PseudoOpcode = Mips::BLT;
2649 case Mips::BLEImmMacro:
2650 PseudoOpcode = Mips::BLE;
2652 case Mips::BGEImmMacro:
2653 PseudoOpcode = Mips::BGE;
2655 case Mips::BGTImmMacro:
2656 PseudoOpcode = Mips::BGT;
2658 case Mips::BLTUImmMacro:
2659 PseudoOpcode = Mips::BLTU;
2661 case Mips::BLEUImmMacro:
2662 PseudoOpcode = Mips::BLEU;
2664 case Mips::BGEUImmMacro:
2665 PseudoOpcode = Mips::BGEU;
2667 case Mips::BGTUImmMacro:
2668 PseudoOpcode = Mips::BGTU;
2670 case Mips::BLTLImmMacro:
2671 PseudoOpcode = Mips::BLTL;
2673 case Mips::BLELImmMacro:
2674 PseudoOpcode = Mips::BLEL;
2676 case Mips::BGELImmMacro:
2677 PseudoOpcode = Mips::BGEL;
2679 case Mips::BGTLImmMacro:
2680 PseudoOpcode = Mips::BGTL;
2682 case Mips::BLTULImmMacro:
2683 PseudoOpcode = Mips::BLTUL;
2685 case Mips::BLEULImmMacro:
2686 PseudoOpcode = Mips::BLEUL;
2688 case Mips::BGEULImmMacro:
2689 PseudoOpcode = Mips::BGEUL;
2691 case Mips::BGTULImmMacro:
2692 PseudoOpcode = Mips::BGTUL;
2696 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2697 false, IDLoc, Instructions))
2701 switch (PseudoOpcode) {
2706 AcceptsEquality = false;
2707 ReverseOrderSLT = false;
2708 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2709 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2710 ZeroSrcOpcode = Mips::BGTZ;
2711 ZeroTrgOpcode = Mips::BLTZ;
2717 AcceptsEquality = true;
2718 ReverseOrderSLT = true;
2719 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2720 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2721 ZeroSrcOpcode = Mips::BGEZ;
2722 ZeroTrgOpcode = Mips::BLEZ;
2728 AcceptsEquality = true;
2729 ReverseOrderSLT = false;
2730 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2731 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2732 ZeroSrcOpcode = Mips::BLEZ;
2733 ZeroTrgOpcode = Mips::BGEZ;
2739 AcceptsEquality = false;
2740 ReverseOrderSLT = true;
2741 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2742 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2743 ZeroSrcOpcode = Mips::BLTZ;
2744 ZeroTrgOpcode = Mips::BGTZ;
2747 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2750 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2751 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2752 if (IsSrcRegZero && IsTrgRegZero) {
2753 // FIXME: All of these Opcode-specific if's are needed for compatibility
2754 // with GAS' behaviour. However, they may not generate the most efficient
2755 // code in some circumstances.
2756 if (PseudoOpcode == Mips::BLT) {
2757 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2761 if (PseudoOpcode == Mips::BLE) {
2762 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2764 Warning(IDLoc, "branch is always taken");
2767 if (PseudoOpcode == Mips::BGE) {
2768 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2770 Warning(IDLoc, "branch is always taken");
2773 if (PseudoOpcode == Mips::BGT) {
2774 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2778 if (PseudoOpcode == Mips::BGTU) {
2779 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2780 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2783 if (AcceptsEquality) {
2784 // If both registers are $0 and the pseudo-branch accepts equality, it
2785 // will always be taken, so we emit an unconditional branch.
2786 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2787 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2788 Warning(IDLoc, "branch is always taken");
2791 // If both registers are $0 and the pseudo-branch does not accept
2792 // equality, it will never be taken, so we don't have to emit anything.
2795 if (IsSrcRegZero || IsTrgRegZero) {
2796 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2797 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2798 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2799 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2800 // the pseudo-branch will never be taken, so we don't emit anything.
2801 // This only applies to unsigned pseudo-branches.
2804 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2805 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2806 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2807 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2808 // the pseudo-branch will always be taken, so we emit an unconditional
2810 // This only applies to unsigned pseudo-branches.
2811 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2812 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2813 Warning(IDLoc, "branch is always taken");
2817 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2818 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2819 // the pseudo-branch will be taken only when the non-zero register is
2820 // different from 0, so we emit a BNEZ.
2822 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2823 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2824 // the pseudo-branch will be taken only when the non-zero register is
2825 // equal to 0, so we emit a BEQZ.
2827 // Because only BLEU and BGEU branch on equality, we can use the
2828 // AcceptsEquality variable to decide when to emit the BEQZ.
2829 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2830 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2831 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2834 // If we have a signed pseudo-branch and one of the registers is $0,
2835 // we can use an appropriate compare-to-zero branch. We select which one
2836 // to use in the switch statement above.
2837 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2838 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2839 IDLoc, Instructions);
2843 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2844 // expansions. If it is not available, we return.
2845 unsigned ATRegNum = getATReg(IDLoc);
2849 if (!EmittedNoMacroWarning)
2850 warnIfNoMacro(IDLoc);
2852 // SLT fits well with 2 of our 4 pseudo-branches:
2853 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2854 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2855 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2856 // This is accomplished by using a BNEZ with the result of the SLT.
2858 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2859 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2860 // Because only BGE and BLE branch on equality, we can use the
2861 // AcceptsEquality variable to decide when to emit the BEQZ.
2862 // Note that the order of the SLT arguments doesn't change between
2865 // The same applies to the unsigned variants, except that SLTu is used
2867 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2868 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2869 IDLoc, Instructions);
2871 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2872 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2873 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2878 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2879 SmallVectorImpl<MCInst> &Instructions,
2880 const bool IsMips64, const bool Signed) {
2881 if (hasMips32r6()) {
2882 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2886 warnIfNoMacro(IDLoc);
2888 const MCOperand &RsRegOp = Inst.getOperand(0);
2889 assert(RsRegOp.isReg() && "expected register operand kind");
2890 unsigned RsReg = RsRegOp.getReg();
2892 const MCOperand &RtRegOp = Inst.getOperand(1);
2893 assert(RtRegOp.isReg() && "expected register operand kind");
2894 unsigned RtReg = RtRegOp.getReg();
2899 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2900 ZeroReg = Mips::ZERO_64;
2902 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2903 ZeroReg = Mips::ZERO;
2906 bool UseTraps = useTraps();
2908 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2909 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2910 Warning(IDLoc, "dividing zero by zero");
2912 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2914 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2918 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2922 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2927 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2928 Warning(IDLoc, "division by zero");
2931 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2935 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2940 // FIXME: The values for these two BranchTarget variables may be different in
2941 // micromips. These magic numbers need to be removed.
2942 unsigned BranchTargetNoTraps;
2943 unsigned BranchTarget;
2946 BranchTarget = IsMips64 ? 12 : 8;
2947 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2949 BranchTarget = IsMips64 ? 20 : 16;
2950 BranchTargetNoTraps = 8;
2951 // Branch to the li instruction.
2952 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2956 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2959 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2962 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2966 unsigned ATReg = getATReg(IDLoc);
2970 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2972 // Branch to the mflo instruction.
2973 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2974 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2975 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2977 // Branch to the mflo instruction.
2978 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2979 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2983 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2985 // Branch to the mflo instruction.
2986 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2987 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2988 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2990 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2994 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
2995 SmallVectorImpl<MCInst> &Instructions) {
2996 if (hasMips32r6() || hasMips64r6()) {
2997 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3001 warnIfNoMacro(IDLoc);
3003 const MCOperand &DstRegOp = Inst.getOperand(0);
3004 assert(DstRegOp.isReg() && "expected register operand kind");
3006 const MCOperand &SrcRegOp = Inst.getOperand(1);
3007 assert(SrcRegOp.isReg() && "expected register operand kind");
3009 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3010 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3012 unsigned DstReg = DstRegOp.getReg();
3013 unsigned SrcReg = SrcRegOp.getReg();
3014 int64_t OffsetValue = OffsetImmOp.getImm();
3016 // NOTE: We always need AT for ULHU, as it is always used as the source
3017 // register for one of the LBu's.
3018 unsigned ATReg = getATReg(IDLoc);
3022 // When the value of offset+1 does not fit in 16 bits, we have to load the
3023 // offset in AT, (D)ADDu the original source register (if there was one), and
3024 // then use AT as the source register for the 2 generated LBu's.
3025 bool LoadedOffsetInAT = false;
3026 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3027 LoadedOffsetInAT = true;
3029 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3030 true, IDLoc, Instructions))
3033 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3034 // because it will make our output more similar to GAS'. For example,
3035 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3036 // instead of just an "ori $1, $9, 32768".
3037 // NOTE: If there is no source register specified in the ULHU, the parser
3038 // will interpret it as $0.
3039 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3040 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3043 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3044 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3045 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3047 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3049 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3050 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3052 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3053 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3056 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3058 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3059 FirstLbuOffset, IDLoc, Instructions);
3061 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3064 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3066 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3071 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3072 SmallVectorImpl<MCInst> &Instructions) {
3073 if (hasMips32r6() || hasMips64r6()) {
3074 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3078 const MCOperand &DstRegOp = Inst.getOperand(0);
3079 assert(DstRegOp.isReg() && "expected register operand kind");
3081 const MCOperand &SrcRegOp = Inst.getOperand(1);
3082 assert(SrcRegOp.isReg() && "expected register operand kind");
3084 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3085 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3087 unsigned SrcReg = SrcRegOp.getReg();
3088 int64_t OffsetValue = OffsetImmOp.getImm();
3091 // When the value of offset+3 does not fit in 16 bits, we have to load the
3092 // offset in AT, (D)ADDu the original source register (if there was one), and
3093 // then use AT as the source register for the generated LWL and LWR.
3094 bool LoadedOffsetInAT = false;
3095 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3096 ATReg = getATReg(IDLoc);
3099 LoadedOffsetInAT = true;
3101 warnIfNoMacro(IDLoc);
3103 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3104 true, IDLoc, Instructions))
3107 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3108 // because it will make our output more similar to GAS'. For example,
3109 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3110 // instead of just an "ori $1, $9, 32768".
3111 // NOTE: If there is no source register specified in the ULW, the parser
3112 // will interpret it as $0.
3113 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3114 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3117 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3118 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3120 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3121 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3123 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3124 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3127 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3130 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3136 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3137 SmallVectorImpl<MCInst> &Instructions) {
3139 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3140 assert (Inst.getOperand(0).isReg() &&
3141 Inst.getOperand(1).isReg() &&
3142 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3144 unsigned ATReg = Mips::NoRegister;
3145 unsigned FinalDstReg = Mips::NoRegister;
3146 unsigned DstReg = Inst.getOperand(0).getReg();
3147 unsigned SrcReg = Inst.getOperand(1).getReg();
3148 int64_t ImmValue = Inst.getOperand(2).getImm();
3150 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3152 unsigned FinalOpcode = Inst.getOpcode();
3154 if (DstReg == SrcReg) {
3155 ATReg = getATReg(Inst.getLoc());
3158 FinalDstReg = DstReg;
3162 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3163 switch (FinalOpcode) {
3165 llvm_unreachable("unimplemented expansion");
3167 FinalOpcode = Mips::ADD;
3170 FinalOpcode = Mips::ADDu;
3173 FinalOpcode = Mips::AND;
3175 case (Mips::NORImm):
3176 FinalOpcode = Mips::NOR;
3179 FinalOpcode = Mips::OR;
3182 FinalOpcode = Mips::SLT;
3185 FinalOpcode = Mips::SLTu;
3188 FinalOpcode = Mips::XOR;
3192 if (FinalDstReg == Mips::NoRegister)
3193 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3195 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3202 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3203 SmallVectorImpl<MCInst> &Instructions) {
3204 if (hasShortDelaySlot)
3205 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3207 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3210 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3211 unsigned TrgReg, bool Is64Bit,
3212 SmallVectorImpl<MCInst> &Instructions) {
3213 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3217 void MipsAsmParser::createCpRestoreMemOp(
3218 bool IsLoad, int StackOffset, SMLoc IDLoc,
3219 SmallVectorImpl<MCInst> &Instructions) {
3220 // If the offset can not fit into 16 bits, we need to expand.
3221 if (!isInt<16>(StackOffset)) {
3223 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3224 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3225 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3226 MemInst.addOperand(MCOperand::createImm(StackOffset));
3227 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3231 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3235 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3236 // As described by the Mips32r2 spec, the registers Rd and Rs for
3237 // jalr.hb must be different.
3238 unsigned Opcode = Inst.getOpcode();
3240 if (Opcode == Mips::JALR_HB &&
3241 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3242 return Match_RequiresDifferentSrcAndDst;
3244 return Match_Success;
3247 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3248 uint64_t ErrorInfo) {
3249 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3250 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3251 if (ErrorLoc == SMLoc())
3258 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3259 OperandVector &Operands,
3261 uint64_t &ErrorInfo,
3262 bool MatchingInlineAsm) {
3265 SmallVector<MCInst, 8> Instructions;
3266 unsigned MatchResult =
3267 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3269 switch (MatchResult) {
3270 case Match_Success: {
3271 if (processInstruction(Inst, IDLoc, Instructions))
3273 for (unsigned i = 0; i < Instructions.size(); i++)
3274 Out.EmitInstruction(Instructions[i], STI);
3277 case Match_MissingFeature:
3278 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3280 case Match_InvalidOperand: {
3281 SMLoc ErrorLoc = IDLoc;
3282 if (ErrorInfo != ~0ULL) {
3283 if (ErrorInfo >= Operands.size())
3284 return Error(IDLoc, "too few operands for instruction");
3286 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3287 if (ErrorLoc == SMLoc())
3291 return Error(ErrorLoc, "invalid operand for instruction");
3293 case Match_MnemonicFail:
3294 return Error(IDLoc, "invalid instruction");
3295 case Match_RequiresDifferentSrcAndDst:
3296 return Error(IDLoc, "source and destination must be different");
3298 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3301 llvm_unreachable("Implement any new match types added!");
3304 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3305 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3306 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3307 ") without \".set noat\"");
3310 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3311 if (!AssemblerOptions.back()->isMacro())
3312 Warning(Loc, "macro instruction expanded into multiple instructions");
3316 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3317 SMRange Range, bool ShowColors) {
3318 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3319 Range, SMFixIt(Range, FixMsg),
3323 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3326 CC = StringSwitch<unsigned>(Name)
3362 if (!(isABI_N32() || isABI_N64()))
3365 if (12 <= CC && CC <= 15) {
3366 // Name is one of t4-t7
3367 AsmToken RegTok = getLexer().peekTok();
3368 SMRange RegRange = RegTok.getLocRange();
3370 StringRef FixedName = StringSwitch<StringRef>(Name)
3376 assert(FixedName != "" && "Register name is not one of t4-t7.");
3378 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3379 "Did you mean $" + FixedName + "?", RegRange);
3382 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3383 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3384 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3385 if (8 <= CC && CC <= 11)
3389 CC = StringSwitch<unsigned>(Name)
3401 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3404 CC = StringSwitch<unsigned>(Name)
3405 .Case("hwr_cpunum", 0)
3406 .Case("hwr_synci_step", 1)
3408 .Case("hwr_ccres", 3)
3409 .Case("hwr_ulr", 29)
3415 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3417 if (Name[0] == 'f') {
3418 StringRef NumString = Name.substr(1);
3420 if (NumString.getAsInteger(10, IntVal))
3421 return -1; // This is not an integer.
3422 if (IntVal > 31) // Maximum index for fpu register.
3429 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3431 if (Name.startswith("fcc")) {
3432 StringRef NumString = Name.substr(3);
3434 if (NumString.getAsInteger(10, IntVal))
3435 return -1; // This is not an integer.
3436 if (IntVal > 7) // There are only 8 fcc registers.
3443 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3445 if (Name.startswith("ac")) {
3446 StringRef NumString = Name.substr(2);
3448 if (NumString.getAsInteger(10, IntVal))
3449 return -1; // This is not an integer.
3450 if (IntVal > 3) // There are only 3 acc registers.
3457 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3460 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3469 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3472 CC = StringSwitch<unsigned>(Name)
3475 .Case("msaaccess", 2)
3477 .Case("msamodify", 4)
3478 .Case("msarequest", 5)
3480 .Case("msaunmap", 7)
3486 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3487 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3489 reportParseError(Loc,
3490 "pseudo-instruction requires $at, which is not available");
3493 unsigned AT = getReg(
3494 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3498 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3499 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3502 unsigned MipsAsmParser::getGPR(int RegNo) {
3503 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3507 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3509 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3512 return getReg(RegClass, RegNum);
3515 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3516 MCAsmParser &Parser = getParser();
3517 DEBUG(dbgs() << "parseOperand\n");
3519 // Check if the current operand has a custom associated parser, if so, try to
3520 // custom parse the operand, or fallback to the general approach.
3521 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3522 if (ResTy == MatchOperand_Success)
3524 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3525 // there was a match, but an error occurred, in which case, just return that
3526 // the operand parsing failed.
3527 if (ResTy == MatchOperand_ParseFail)
3530 DEBUG(dbgs() << ".. Generic Parser\n");
3532 switch (getLexer().getKind()) {
3534 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3536 case AsmToken::Dollar: {
3537 // Parse the register.
3538 SMLoc S = Parser.getTok().getLoc();
3540 // Almost all registers have been parsed by custom parsers. There is only
3541 // one exception to this. $zero (and it's alias $0) will reach this point
3542 // for div, divu, and similar instructions because it is not an operand
3543 // to the instruction definition but an explicit register. Special case
3544 // this situation for now.
3545 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3548 // Maybe it is a symbol reference.
3549 StringRef Identifier;
3550 if (Parser.parseIdentifier(Identifier))
3553 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3554 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3555 // Otherwise create a symbol reference.
3557 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3559 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3562 // Else drop to expression parsing.
3563 case AsmToken::LParen:
3564 case AsmToken::Minus:
3565 case AsmToken::Plus:
3566 case AsmToken::Integer:
3567 case AsmToken::Tilde:
3568 case AsmToken::String: {
3569 DEBUG(dbgs() << ".. generic integer\n");
3570 OperandMatchResultTy ResTy = parseImm(Operands);
3571 return ResTy != MatchOperand_Success;
3573 case AsmToken::Percent: {
3574 // It is a symbol reference or constant expression.
3575 const MCExpr *IdVal;
3576 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3577 if (parseRelocOperand(IdVal))
3580 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3582 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3584 } // case AsmToken::Percent
3585 } // switch(getLexer().getKind())
3589 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3590 StringRef RelocStr) {
3592 // Check the type of the expression.
3593 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3594 // It's a constant, evaluate reloc value.
3596 switch (getVariantKind(RelocStr)) {
3597 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3598 // Get the 1st 16-bits.
3599 Val = MCE->getValue() & 0xffff;
3601 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3602 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3603 // 16 bits being negative.
3604 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3606 case MCSymbolRefExpr::VK_Mips_HIGHER:
3607 // Get the 3rd 16-bits.
3608 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3610 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3611 // Get the 4th 16-bits.
3612 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3615 report_fatal_error("unsupported reloc value");
3617 return MCConstantExpr::create(Val, getContext());
3620 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3621 // It's a symbol, create a symbolic expression from the symbol.
3622 const MCSymbol *Symbol = &MSRE->getSymbol();
3623 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3624 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3628 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3629 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3631 // Try to create target expression.
3632 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3633 return MipsMCExpr::create(VK, Expr, getContext());
3635 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3636 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3637 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3641 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3642 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3643 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3646 // Just return the original expression.
3650 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3652 switch (Expr->getKind()) {
3653 case MCExpr::Constant:
3655 case MCExpr::SymbolRef:
3656 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3657 case MCExpr::Binary:
3658 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3659 if (!isEvaluated(BE->getLHS()))
3661 return isEvaluated(BE->getRHS());
3664 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3665 case MCExpr::Target:
3671 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3672 MCAsmParser &Parser = getParser();
3673 Parser.Lex(); // Eat the % token.
3674 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3675 if (Tok.isNot(AsmToken::Identifier))
3678 std::string Str = Tok.getIdentifier();
3680 Parser.Lex(); // Eat the identifier.
3681 // Now make an expression from the rest of the operand.
3682 const MCExpr *IdVal;
3685 if (getLexer().getKind() == AsmToken::LParen) {
3687 Parser.Lex(); // Eat the '(' token.
3688 if (getLexer().getKind() == AsmToken::Percent) {
3689 Parser.Lex(); // Eat the % token.
3690 const AsmToken &nextTok = Parser.getTok();
3691 if (nextTok.isNot(AsmToken::Identifier))
3694 Str += nextTok.getIdentifier();
3695 Parser.Lex(); // Eat the identifier.
3696 if (getLexer().getKind() != AsmToken::LParen)
3701 if (getParser().parseParenExpression(IdVal, EndLoc))
3704 while (getLexer().getKind() == AsmToken::RParen)
3705 Parser.Lex(); // Eat the ')' token.
3708 return true; // Parenthesis must follow the relocation operand.
3710 Res = evaluateRelocExpr(IdVal, Str);
3714 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3716 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3717 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3718 if (ResTy == MatchOperand_Success) {
3719 assert(Operands.size() == 1);
3720 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3721 StartLoc = Operand.getStartLoc();
3722 EndLoc = Operand.getEndLoc();
3724 // AFAIK, we only support numeric registers and named GPR's in CFI
3726 // Don't worry about eating tokens before failing. Using an unrecognised
3727 // register is a parse error.
3728 if (Operand.isGPRAsmReg()) {
3729 // Resolve to GPR32 or GPR64 appropriately.
3730 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3733 return (RegNo == (unsigned)-1);
3736 assert(Operands.size() == 0);
3737 return (RegNo == (unsigned)-1);
3740 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3741 MCAsmParser &Parser = getParser();
3744 unsigned NumOfLParen = 0;
3746 while (getLexer().getKind() == AsmToken::LParen) {
3751 switch (getLexer().getKind()) {
3754 case AsmToken::Identifier:
3755 case AsmToken::LParen:
3756 case AsmToken::Integer:
3757 case AsmToken::Minus:
3758 case AsmToken::Plus:
3760 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3762 Result = (getParser().parseExpression(Res));
3763 while (getLexer().getKind() == AsmToken::RParen)
3766 case AsmToken::Percent:
3767 Result = parseRelocOperand(Res);
3772 MipsAsmParser::OperandMatchResultTy
3773 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3774 MCAsmParser &Parser = getParser();
3775 DEBUG(dbgs() << "parseMemOperand\n");
3776 const MCExpr *IdVal = nullptr;
3778 bool isParenExpr = false;
3779 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3780 // First operand is the offset.
3781 S = Parser.getTok().getLoc();
3783 if (getLexer().getKind() == AsmToken::LParen) {
3788 if (getLexer().getKind() != AsmToken::Dollar) {
3789 if (parseMemOffset(IdVal, isParenExpr))
3790 return MatchOperand_ParseFail;
3792 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3793 if (Tok.isNot(AsmToken::LParen)) {
3794 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3795 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3797 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3798 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3799 return MatchOperand_Success;
3801 if (Tok.is(AsmToken::EndOfStatement)) {
3803 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3805 // Zero register assumed, add a memory operand with ZERO as its base.
3806 // "Base" will be managed by k_Memory.
3807 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3810 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3811 return MatchOperand_Success;
3813 Error(Parser.getTok().getLoc(), "'(' expected");
3814 return MatchOperand_ParseFail;
3817 Parser.Lex(); // Eat the '(' token.
3820 Res = parseAnyRegister(Operands);
3821 if (Res != MatchOperand_Success)
3824 if (Parser.getTok().isNot(AsmToken::RParen)) {
3825 Error(Parser.getTok().getLoc(), "')' expected");
3826 return MatchOperand_ParseFail;
3829 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3831 Parser.Lex(); // Eat the ')' token.
3834 IdVal = MCConstantExpr::create(0, getContext());
3836 // Replace the register operand with the memory operand.
3837 std::unique_ptr<MipsOperand> op(
3838 static_cast<MipsOperand *>(Operands.back().release()));
3839 // Remove the register from the operands.
3840 // "op" will be managed by k_Memory.
3841 Operands.pop_back();
3842 // Add the memory operand.
3843 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3845 if (IdVal->evaluateAsAbsolute(Imm))
3846 IdVal = MCConstantExpr::create(Imm, getContext());
3847 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3848 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3852 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3853 return MatchOperand_Success;
3856 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3857 MCAsmParser &Parser = getParser();
3858 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3860 SMLoc S = Parser.getTok().getLoc();
3862 if (Sym->isVariable())
3863 Expr = Sym->getVariableValue();
3866 if (Expr->getKind() == MCExpr::SymbolRef) {
3867 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3868 StringRef DefSymbol = Ref->getSymbol().getName();
3869 if (DefSymbol.startswith("$")) {
3870 OperandMatchResultTy ResTy =
3871 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3872 if (ResTy == MatchOperand_Success) {
3875 } else if (ResTy == MatchOperand_ParseFail)
3876 llvm_unreachable("Should never ParseFail");
3879 } else if (Expr->getKind() == MCExpr::Constant) {
3881 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3883 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3890 MipsAsmParser::OperandMatchResultTy
3891 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3892 StringRef Identifier,
3894 int Index = matchCPURegisterName(Identifier);
3896 Operands.push_back(MipsOperand::createGPRReg(
3897 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3898 return MatchOperand_Success;
3901 Index = matchHWRegsRegisterName(Identifier);
3903 Operands.push_back(MipsOperand::createHWRegsReg(
3904 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3905 return MatchOperand_Success;
3908 Index = matchFPURegisterName(Identifier);
3910 Operands.push_back(MipsOperand::createFGRReg(
3911 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3912 return MatchOperand_Success;
3915 Index = matchFCCRegisterName(Identifier);
3917 Operands.push_back(MipsOperand::createFCCReg(
3918 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3919 return MatchOperand_Success;
3922 Index = matchACRegisterName(Identifier);
3924 Operands.push_back(MipsOperand::createACCReg(
3925 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3926 return MatchOperand_Success;
3929 Index = matchMSA128RegisterName(Identifier);
3931 Operands.push_back(MipsOperand::createMSA128Reg(
3932 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3933 return MatchOperand_Success;
3936 Index = matchMSA128CtrlRegisterName(Identifier);
3938 Operands.push_back(MipsOperand::createMSACtrlReg(
3939 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3940 return MatchOperand_Success;
3943 return MatchOperand_NoMatch;
3946 MipsAsmParser::OperandMatchResultTy
3947 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3948 MCAsmParser &Parser = getParser();
3949 auto Token = Parser.getLexer().peekTok(false);
3951 if (Token.is(AsmToken::Identifier)) {
3952 DEBUG(dbgs() << ".. identifier\n");
3953 StringRef Identifier = Token.getIdentifier();
3954 OperandMatchResultTy ResTy =
3955 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3957 } else if (Token.is(AsmToken::Integer)) {
3958 DEBUG(dbgs() << ".. integer\n");
3959 Operands.push_back(MipsOperand::createNumericReg(
3960 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3962 return MatchOperand_Success;
3965 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3967 return MatchOperand_NoMatch;
3970 MipsAsmParser::OperandMatchResultTy
3971 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3972 MCAsmParser &Parser = getParser();
3973 DEBUG(dbgs() << "parseAnyRegister\n");
3975 auto Token = Parser.getTok();
3977 SMLoc S = Token.getLoc();
3979 if (Token.isNot(AsmToken::Dollar)) {
3980 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3981 if (Token.is(AsmToken::Identifier)) {
3982 if (searchSymbolAlias(Operands))
3983 return MatchOperand_Success;
3985 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3986 return MatchOperand_NoMatch;
3988 DEBUG(dbgs() << ".. $\n");
3990 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3991 if (ResTy == MatchOperand_Success) {
3993 Parser.Lex(); // identifier
3998 MipsAsmParser::OperandMatchResultTy
3999 MipsAsmParser::parseImm(OperandVector &Operands) {
4000 MCAsmParser &Parser = getParser();
4001 switch (getLexer().getKind()) {
4003 return MatchOperand_NoMatch;
4004 case AsmToken::LParen:
4005 case AsmToken::Minus:
4006 case AsmToken::Plus:
4007 case AsmToken::Integer:
4008 case AsmToken::Tilde:
4009 case AsmToken::String:
4013 const MCExpr *IdVal;
4014 SMLoc S = Parser.getTok().getLoc();
4015 if (getParser().parseExpression(IdVal))
4016 return MatchOperand_ParseFail;
4018 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4019 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4020 return MatchOperand_Success;
4023 MipsAsmParser::OperandMatchResultTy
4024 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4025 MCAsmParser &Parser = getParser();
4026 DEBUG(dbgs() << "parseJumpTarget\n");
4028 SMLoc S = getLexer().getLoc();
4030 // Integers and expressions are acceptable
4031 OperandMatchResultTy ResTy = parseImm(Operands);
4032 if (ResTy != MatchOperand_NoMatch)
4035 // Registers are a valid target and have priority over symbols.
4036 ResTy = parseAnyRegister(Operands);
4037 if (ResTy != MatchOperand_NoMatch)
4040 const MCExpr *Expr = nullptr;
4041 if (Parser.parseExpression(Expr)) {
4042 // We have no way of knowing if a symbol was consumed so we must ParseFail
4043 return MatchOperand_ParseFail;
4046 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4047 return MatchOperand_Success;
4050 MipsAsmParser::OperandMatchResultTy
4051 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4052 MCAsmParser &Parser = getParser();
4053 const MCExpr *IdVal;
4054 // If the first token is '$' we may have register operand.
4055 if (Parser.getTok().is(AsmToken::Dollar))
4056 return MatchOperand_NoMatch;
4057 SMLoc S = Parser.getTok().getLoc();
4058 if (getParser().parseExpression(IdVal))
4059 return MatchOperand_ParseFail;
4060 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4061 assert(MCE && "Unexpected MCExpr type.");
4062 int64_t Val = MCE->getValue();
4063 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4064 Operands.push_back(MipsOperand::CreateImm(
4065 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4066 return MatchOperand_Success;
4069 MipsAsmParser::OperandMatchResultTy
4070 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4071 MCAsmParser &Parser = getParser();
4072 switch (getLexer().getKind()) {
4074 return MatchOperand_NoMatch;
4075 case AsmToken::LParen:
4076 case AsmToken::Plus:
4077 case AsmToken::Minus:
4078 case AsmToken::Integer:
4083 SMLoc S = Parser.getTok().getLoc();
4085 if (getParser().parseExpression(Expr))
4086 return MatchOperand_ParseFail;
4089 if (!Expr->evaluateAsAbsolute(Val)) {
4090 Error(S, "expected immediate value");
4091 return MatchOperand_ParseFail;
4094 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4095 // and because the CPU always adds one to the immediate field, the allowed
4096 // range becomes 1..4. We'll only check the range here and will deal
4097 // with the addition/subtraction when actually decoding/encoding
4099 if (Val < 1 || Val > 4) {
4100 Error(S, "immediate not in range (1..4)");
4101 return MatchOperand_ParseFail;
4105 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4106 return MatchOperand_Success;
4109 MipsAsmParser::OperandMatchResultTy
4110 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4111 MCAsmParser &Parser = getParser();
4112 SmallVector<unsigned, 10> Regs;
4114 unsigned PrevReg = Mips::NoRegister;
4115 bool RegRange = false;
4116 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4118 if (Parser.getTok().isNot(AsmToken::Dollar))
4119 return MatchOperand_ParseFail;
4121 SMLoc S = Parser.getTok().getLoc();
4122 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4123 SMLoc E = getLexer().getLoc();
4124 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4125 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4127 // Remove last register operand because registers from register range
4128 // should be inserted first.
4129 if (RegNo == Mips::RA) {
4130 Regs.push_back(RegNo);
4132 unsigned TmpReg = PrevReg + 1;
4133 while (TmpReg <= RegNo) {
4134 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4135 Error(E, "invalid register operand");
4136 return MatchOperand_ParseFail;
4140 Regs.push_back(TmpReg++);
4146 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4147 (RegNo != Mips::RA)) {
4148 Error(E, "$16 or $31 expected");
4149 return MatchOperand_ParseFail;
4150 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4151 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4152 Error(E, "invalid register operand");
4153 return MatchOperand_ParseFail;
4154 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4155 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4156 Error(E, "consecutive register numbers expected");
4157 return MatchOperand_ParseFail;
4160 Regs.push_back(RegNo);
4163 if (Parser.getTok().is(AsmToken::Minus))
4166 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4167 !Parser.getTok().isNot(AsmToken::Comma)) {
4168 Error(E, "',' or '-' expected");
4169 return MatchOperand_ParseFail;
4172 Lex(); // Consume comma or minus
4173 if (Parser.getTok().isNot(AsmToken::Dollar))
4179 SMLoc E = Parser.getTok().getLoc();
4180 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4181 parseMemOperand(Operands);
4182 return MatchOperand_Success;
4185 MipsAsmParser::OperandMatchResultTy
4186 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4187 MCAsmParser &Parser = getParser();
4189 SMLoc S = Parser.getTok().getLoc();
4190 if (parseAnyRegister(Operands) != MatchOperand_Success)
4191 return MatchOperand_ParseFail;
4193 SMLoc E = Parser.getTok().getLoc();
4194 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4195 unsigned Reg = Op.getGPR32Reg();
4196 Operands.pop_back();
4197 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4198 return MatchOperand_Success;
4201 MipsAsmParser::OperandMatchResultTy
4202 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4203 MCAsmParser &Parser = getParser();
4204 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4205 SmallVector<unsigned, 10> Regs;
4207 if (Parser.getTok().isNot(AsmToken::Dollar))
4208 return MatchOperand_ParseFail;
4210 SMLoc S = Parser.getTok().getLoc();
4212 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4213 return MatchOperand_ParseFail;
4215 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4216 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4217 Regs.push_back(RegNo);
4219 SMLoc E = Parser.getTok().getLoc();
4220 if (Parser.getTok().isNot(AsmToken::Comma)) {
4221 Error(E, "',' expected");
4222 return MatchOperand_ParseFail;
4228 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4229 return MatchOperand_ParseFail;
4231 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4232 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4233 Regs.push_back(RegNo);
4235 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4237 return MatchOperand_Success;
4240 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4242 MCSymbolRefExpr::VariantKind VK =
4243 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4244 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4245 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4246 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4247 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4248 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4249 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4250 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4251 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4252 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4253 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4254 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4255 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4256 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4257 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4258 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4259 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4260 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4261 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4262 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4263 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4264 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4265 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4266 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4267 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4268 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4269 .Default(MCSymbolRefExpr::VK_None);
4271 assert(VK != MCSymbolRefExpr::VK_None);
4276 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4278 /// ::= '(', register, ')'
4279 /// handle it before we iterate so we don't get tripped up by the lack of
4281 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4282 MCAsmParser &Parser = getParser();
4283 if (getLexer().is(AsmToken::LParen)) {
4285 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4287 if (parseOperand(Operands, Name)) {
4288 SMLoc Loc = getLexer().getLoc();
4289 Parser.eatToEndOfStatement();
4290 return Error(Loc, "unexpected token in argument list");
4292 if (Parser.getTok().isNot(AsmToken::RParen)) {
4293 SMLoc Loc = getLexer().getLoc();
4294 Parser.eatToEndOfStatement();
4295 return Error(Loc, "unexpected token, expected ')'");
4298 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4304 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4305 /// either one of these.
4306 /// ::= '[', register, ']'
4307 /// ::= '[', integer, ']'
4308 /// handle it before we iterate so we don't get tripped up by the lack of
4310 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4311 OperandVector &Operands) {
4312 MCAsmParser &Parser = getParser();
4313 if (getLexer().is(AsmToken::LBrac)) {
4315 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4317 if (parseOperand(Operands, Name)) {
4318 SMLoc Loc = getLexer().getLoc();
4319 Parser.eatToEndOfStatement();
4320 return Error(Loc, "unexpected token in argument list");
4322 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4323 SMLoc Loc = getLexer().getLoc();
4324 Parser.eatToEndOfStatement();
4325 return Error(Loc, "unexpected token, expected ']'");
4328 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4334 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4335 SMLoc NameLoc, OperandVector &Operands) {
4336 MCAsmParser &Parser = getParser();
4337 DEBUG(dbgs() << "ParseInstruction\n");
4339 // We have reached first instruction, module directive are now forbidden.
4340 getTargetStreamer().forbidModuleDirective();
4342 // Check if we have valid mnemonic
4343 if (!mnemonicIsValid(Name, 0)) {
4344 Parser.eatToEndOfStatement();
4345 return Error(NameLoc, "unknown instruction");
4347 // First operand in MCInst is instruction mnemonic.
4348 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4350 // Read the remaining operands.
4351 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4352 // Read the first operand.
4353 if (parseOperand(Operands, Name)) {
4354 SMLoc Loc = getLexer().getLoc();
4355 Parser.eatToEndOfStatement();
4356 return Error(Loc, "unexpected token in argument list");
4358 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4360 // AFAIK, parenthesis suffixes are never on the first operand
4362 while (getLexer().is(AsmToken::Comma)) {
4363 Parser.Lex(); // Eat the comma.
4364 // Parse and remember the operand.
4365 if (parseOperand(Operands, Name)) {
4366 SMLoc Loc = getLexer().getLoc();
4367 Parser.eatToEndOfStatement();
4368 return Error(Loc, "unexpected token in argument list");
4370 // Parse bracket and parenthesis suffixes before we iterate
4371 if (getLexer().is(AsmToken::LBrac)) {
4372 if (parseBracketSuffix(Name, Operands))
4374 } else if (getLexer().is(AsmToken::LParen) &&
4375 parseParenSuffix(Name, Operands))
4379 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4380 SMLoc Loc = getLexer().getLoc();
4381 Parser.eatToEndOfStatement();
4382 return Error(Loc, "unexpected token in argument list");
4384 Parser.Lex(); // Consume the EndOfStatement.
4388 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4389 MCAsmParser &Parser = getParser();
4390 SMLoc Loc = getLexer().getLoc();
4391 Parser.eatToEndOfStatement();
4392 return Error(Loc, ErrorMsg);
4395 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4396 return Error(Loc, ErrorMsg);
4399 bool MipsAsmParser::parseSetNoAtDirective() {
4400 MCAsmParser &Parser = getParser();
4401 // Line should look like: ".set noat".
4403 // Set the $at register to $0.
4404 AssemblerOptions.back()->setATRegIndex(0);
4406 Parser.Lex(); // Eat "noat".
4408 // If this is not the end of the statement, report an error.
4409 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4410 reportParseError("unexpected token, expected end of statement");
4414 getTargetStreamer().emitDirectiveSetNoAt();
4415 Parser.Lex(); // Consume the EndOfStatement.
4419 bool MipsAsmParser::parseSetAtDirective() {
4420 // Line can be: ".set at", which sets $at to $1
4421 // or ".set at=$reg", which sets $at to $reg.
4422 MCAsmParser &Parser = getParser();
4423 Parser.Lex(); // Eat "at".
4425 if (getLexer().is(AsmToken::EndOfStatement)) {
4426 // No register was specified, so we set $at to $1.
4427 AssemblerOptions.back()->setATRegIndex(1);
4429 getTargetStreamer().emitDirectiveSetAt();
4430 Parser.Lex(); // Consume the EndOfStatement.
4434 if (getLexer().isNot(AsmToken::Equal)) {
4435 reportParseError("unexpected token, expected equals sign");
4438 Parser.Lex(); // Eat "=".
4440 if (getLexer().isNot(AsmToken::Dollar)) {
4441 if (getLexer().is(AsmToken::EndOfStatement)) {
4442 reportParseError("no register specified");
4445 reportParseError("unexpected token, expected dollar sign '$'");
4449 Parser.Lex(); // Eat "$".
4451 // Find out what "reg" is.
4453 const AsmToken &Reg = Parser.getTok();
4454 if (Reg.is(AsmToken::Identifier)) {
4455 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4456 } else if (Reg.is(AsmToken::Integer)) {
4457 AtRegNo = Reg.getIntVal();
4459 reportParseError("unexpected token, expected identifier or integer");
4463 // Check if $reg is a valid register. If it is, set $at to $reg.
4464 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4465 reportParseError("invalid register");
4468 Parser.Lex(); // Eat "reg".
4470 // If this is not the end of the statement, report an error.
4471 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4472 reportParseError("unexpected token, expected end of statement");
4476 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4478 Parser.Lex(); // Consume the EndOfStatement.
4482 bool MipsAsmParser::parseSetReorderDirective() {
4483 MCAsmParser &Parser = getParser();
4485 // If this is not the end of the statement, report an error.
4486 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4487 reportParseError("unexpected token, expected end of statement");
4490 AssemblerOptions.back()->setReorder();
4491 getTargetStreamer().emitDirectiveSetReorder();
4492 Parser.Lex(); // Consume the EndOfStatement.
4496 bool MipsAsmParser::parseSetNoReorderDirective() {
4497 MCAsmParser &Parser = getParser();
4499 // If this is not the end of the statement, report an error.
4500 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4501 reportParseError("unexpected token, expected end of statement");
4504 AssemblerOptions.back()->setNoReorder();
4505 getTargetStreamer().emitDirectiveSetNoReorder();
4506 Parser.Lex(); // Consume the EndOfStatement.
4510 bool MipsAsmParser::parseSetMacroDirective() {
4511 MCAsmParser &Parser = getParser();
4513 // If this is not the end of the statement, report an error.
4514 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4515 reportParseError("unexpected token, expected end of statement");
4518 AssemblerOptions.back()->setMacro();
4519 getTargetStreamer().emitDirectiveSetMacro();
4520 Parser.Lex(); // Consume the EndOfStatement.
4524 bool MipsAsmParser::parseSetNoMacroDirective() {
4525 MCAsmParser &Parser = getParser();
4527 // If this is not the end of the statement, report an error.
4528 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4529 reportParseError("unexpected token, expected end of statement");
4532 if (AssemblerOptions.back()->isReorder()) {
4533 reportParseError("`noreorder' must be set before `nomacro'");
4536 AssemblerOptions.back()->setNoMacro();
4537 getTargetStreamer().emitDirectiveSetNoMacro();
4538 Parser.Lex(); // Consume the EndOfStatement.
4542 bool MipsAsmParser::parseSetMsaDirective() {
4543 MCAsmParser &Parser = getParser();
4546 // If this is not the end of the statement, report an error.
4547 if (getLexer().isNot(AsmToken::EndOfStatement))
4548 return reportParseError("unexpected token, expected end of statement");
4550 setFeatureBits(Mips::FeatureMSA, "msa");
4551 getTargetStreamer().emitDirectiveSetMsa();
4555 bool MipsAsmParser::parseSetNoMsaDirective() {
4556 MCAsmParser &Parser = getParser();
4559 // If this is not the end of the statement, report an error.
4560 if (getLexer().isNot(AsmToken::EndOfStatement))
4561 return reportParseError("unexpected token, expected end of statement");
4563 clearFeatureBits(Mips::FeatureMSA, "msa");
4564 getTargetStreamer().emitDirectiveSetNoMsa();
4568 bool MipsAsmParser::parseSetNoDspDirective() {
4569 MCAsmParser &Parser = getParser();
4570 Parser.Lex(); // Eat "nodsp".
4572 // If this is not the end of the statement, report an error.
4573 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4574 reportParseError("unexpected token, expected end of statement");
4578 clearFeatureBits(Mips::FeatureDSP, "dsp");
4579 getTargetStreamer().emitDirectiveSetNoDsp();
4583 bool MipsAsmParser::parseSetMips16Directive() {
4584 MCAsmParser &Parser = getParser();
4585 Parser.Lex(); // Eat "mips16".
4587 // If this is not the end of the statement, report an error.
4588 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4589 reportParseError("unexpected token, expected end of statement");
4593 setFeatureBits(Mips::FeatureMips16, "mips16");
4594 getTargetStreamer().emitDirectiveSetMips16();
4595 Parser.Lex(); // Consume the EndOfStatement.
4599 bool MipsAsmParser::parseSetNoMips16Directive() {
4600 MCAsmParser &Parser = getParser();
4601 Parser.Lex(); // Eat "nomips16".
4603 // If this is not the end of the statement, report an error.
4604 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4605 reportParseError("unexpected token, expected end of statement");
4609 clearFeatureBits(Mips::FeatureMips16, "mips16");
4610 getTargetStreamer().emitDirectiveSetNoMips16();
4611 Parser.Lex(); // Consume the EndOfStatement.
4615 bool MipsAsmParser::parseSetFpDirective() {
4616 MCAsmParser &Parser = getParser();
4617 MipsABIFlagsSection::FpABIKind FpAbiVal;
4618 // Line can be: .set fp=32
4621 Parser.Lex(); // Eat fp token
4622 AsmToken Tok = Parser.getTok();
4623 if (Tok.isNot(AsmToken::Equal)) {
4624 reportParseError("unexpected token, expected equals sign '='");
4627 Parser.Lex(); // Eat '=' token.
4628 Tok = Parser.getTok();
4630 if (!parseFpABIValue(FpAbiVal, ".set"))
4633 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4634 reportParseError("unexpected token, expected end of statement");
4637 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4638 Parser.Lex(); // Consume the EndOfStatement.
4642 bool MipsAsmParser::parseSetOddSPRegDirective() {
4643 MCAsmParser &Parser = getParser();
4645 Parser.Lex(); // Eat "oddspreg".
4646 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4647 reportParseError("unexpected token, expected end of statement");
4651 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4652 getTargetStreamer().emitDirectiveSetOddSPReg();
4656 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4657 MCAsmParser &Parser = getParser();
4659 Parser.Lex(); // Eat "nooddspreg".
4660 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4661 reportParseError("unexpected token, expected end of statement");
4665 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4666 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4670 bool MipsAsmParser::parseSetPopDirective() {
4671 MCAsmParser &Parser = getParser();
4672 SMLoc Loc = getLexer().getLoc();
4675 if (getLexer().isNot(AsmToken::EndOfStatement))
4676 return reportParseError("unexpected token, expected end of statement");
4678 // Always keep an element on the options "stack" to prevent the user
4679 // from changing the initial options. This is how we remember them.
4680 if (AssemblerOptions.size() == 2)
4681 return reportParseError(Loc, ".set pop with no .set push");
4683 AssemblerOptions.pop_back();
4684 setAvailableFeatures(
4685 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4686 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4688 getTargetStreamer().emitDirectiveSetPop();
4692 bool MipsAsmParser::parseSetPushDirective() {
4693 MCAsmParser &Parser = getParser();
4695 if (getLexer().isNot(AsmToken::EndOfStatement))
4696 return reportParseError("unexpected token, expected end of statement");
4698 // Create a copy of the current assembler options environment and push it.
4699 AssemblerOptions.push_back(
4700 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4702 getTargetStreamer().emitDirectiveSetPush();
4706 bool MipsAsmParser::parseSetSoftFloatDirective() {
4707 MCAsmParser &Parser = getParser();
4709 if (getLexer().isNot(AsmToken::EndOfStatement))
4710 return reportParseError("unexpected token, expected end of statement");
4712 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4713 getTargetStreamer().emitDirectiveSetSoftFloat();
4717 bool MipsAsmParser::parseSetHardFloatDirective() {
4718 MCAsmParser &Parser = getParser();
4720 if (getLexer().isNot(AsmToken::EndOfStatement))
4721 return reportParseError("unexpected token, expected end of statement");
4723 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4724 getTargetStreamer().emitDirectiveSetHardFloat();
4728 bool MipsAsmParser::parseSetAssignment() {
4730 const MCExpr *Value;
4731 MCAsmParser &Parser = getParser();
4733 if (Parser.parseIdentifier(Name))
4734 reportParseError("expected identifier after .set");
4736 if (getLexer().isNot(AsmToken::Comma))
4737 return reportParseError("unexpected token, expected comma");
4740 if (Parser.parseExpression(Value))
4741 return reportParseError("expected valid expression after comma");
4743 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4744 Sym->setVariableValue(Value);
4749 bool MipsAsmParser::parseSetMips0Directive() {
4750 MCAsmParser &Parser = getParser();
4752 if (getLexer().isNot(AsmToken::EndOfStatement))
4753 return reportParseError("unexpected token, expected end of statement");
4755 // Reset assembler options to their initial values.
4756 setAvailableFeatures(
4757 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4758 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4759 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4761 getTargetStreamer().emitDirectiveSetMips0();
4765 bool MipsAsmParser::parseSetArchDirective() {
4766 MCAsmParser &Parser = getParser();
4768 if (getLexer().isNot(AsmToken::Equal))
4769 return reportParseError("unexpected token, expected equals sign");
4773 if (Parser.parseIdentifier(Arch))
4774 return reportParseError("expected arch identifier");
4776 StringRef ArchFeatureName =
4777 StringSwitch<StringRef>(Arch)
4778 .Case("mips1", "mips1")
4779 .Case("mips2", "mips2")
4780 .Case("mips3", "mips3")
4781 .Case("mips4", "mips4")
4782 .Case("mips5", "mips5")
4783 .Case("mips32", "mips32")
4784 .Case("mips32r2", "mips32r2")
4785 .Case("mips32r3", "mips32r3")
4786 .Case("mips32r5", "mips32r5")
4787 .Case("mips32r6", "mips32r6")
4788 .Case("mips64", "mips64")
4789 .Case("mips64r2", "mips64r2")
4790 .Case("mips64r3", "mips64r3")
4791 .Case("mips64r5", "mips64r5")
4792 .Case("mips64r6", "mips64r6")
4793 .Case("cnmips", "cnmips")
4794 .Case("r4000", "mips3") // This is an implementation of Mips3.
4797 if (ArchFeatureName.empty())
4798 return reportParseError("unsupported architecture");
4800 selectArch(ArchFeatureName);
4801 getTargetStreamer().emitDirectiveSetArch(Arch);
4805 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4806 MCAsmParser &Parser = getParser();
4808 if (getLexer().isNot(AsmToken::EndOfStatement))
4809 return reportParseError("unexpected token, expected end of statement");
4813 llvm_unreachable("Unimplemented feature");
4814 case Mips::FeatureDSP:
4815 setFeatureBits(Mips::FeatureDSP, "dsp");
4816 getTargetStreamer().emitDirectiveSetDsp();
4818 case Mips::FeatureMicroMips:
4819 getTargetStreamer().emitDirectiveSetMicroMips();
4821 case Mips::FeatureMips1:
4822 selectArch("mips1");
4823 getTargetStreamer().emitDirectiveSetMips1();
4825 case Mips::FeatureMips2:
4826 selectArch("mips2");
4827 getTargetStreamer().emitDirectiveSetMips2();
4829 case Mips::FeatureMips3:
4830 selectArch("mips3");
4831 getTargetStreamer().emitDirectiveSetMips3();
4833 case Mips::FeatureMips4:
4834 selectArch("mips4");
4835 getTargetStreamer().emitDirectiveSetMips4();
4837 case Mips::FeatureMips5:
4838 selectArch("mips5");
4839 getTargetStreamer().emitDirectiveSetMips5();
4841 case Mips::FeatureMips32:
4842 selectArch("mips32");
4843 getTargetStreamer().emitDirectiveSetMips32();
4845 case Mips::FeatureMips32r2:
4846 selectArch("mips32r2");
4847 getTargetStreamer().emitDirectiveSetMips32R2();
4849 case Mips::FeatureMips32r3:
4850 selectArch("mips32r3");
4851 getTargetStreamer().emitDirectiveSetMips32R3();
4853 case Mips::FeatureMips32r5:
4854 selectArch("mips32r5");
4855 getTargetStreamer().emitDirectiveSetMips32R5();
4857 case Mips::FeatureMips32r6:
4858 selectArch("mips32r6");
4859 getTargetStreamer().emitDirectiveSetMips32R6();
4861 case Mips::FeatureMips64:
4862 selectArch("mips64");
4863 getTargetStreamer().emitDirectiveSetMips64();
4865 case Mips::FeatureMips64r2:
4866 selectArch("mips64r2");
4867 getTargetStreamer().emitDirectiveSetMips64R2();
4869 case Mips::FeatureMips64r3:
4870 selectArch("mips64r3");
4871 getTargetStreamer().emitDirectiveSetMips64R3();
4873 case Mips::FeatureMips64r5:
4874 selectArch("mips64r5");
4875 getTargetStreamer().emitDirectiveSetMips64R5();
4877 case Mips::FeatureMips64r6:
4878 selectArch("mips64r6");
4879 getTargetStreamer().emitDirectiveSetMips64R6();
4885 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4886 MCAsmParser &Parser = getParser();
4887 if (getLexer().isNot(AsmToken::Comma)) {
4888 SMLoc Loc = getLexer().getLoc();
4889 Parser.eatToEndOfStatement();
4890 return Error(Loc, ErrorStr);
4893 Parser.Lex(); // Eat the comma.
4897 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4898 // In this class, it is only used for .cprestore.
4899 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4900 // MipsTargetELFStreamer and MipsAsmParser.
4901 bool MipsAsmParser::isPicAndNotNxxAbi() {
4902 return inPicMode() && !(isABI_N32() || isABI_N64());
4905 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4906 if (AssemblerOptions.back()->isReorder())
4907 Warning(Loc, ".cpload should be inside a noreorder section");
4909 if (inMips16Mode()) {
4910 reportParseError(".cpload is not supported in Mips16 mode");
4914 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4915 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4916 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4917 reportParseError("expected register containing function address");
4921 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4922 if (!RegOpnd.isGPRAsmReg()) {
4923 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4927 // If this is not the end of the statement, report an error.
4928 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4929 reportParseError("unexpected token, expected end of statement");
4933 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4937 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4938 MCAsmParser &Parser = getParser();
4940 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4941 // is used in non-PIC mode.
4943 if (inMips16Mode()) {
4944 reportParseError(".cprestore is not supported in Mips16 mode");
4948 // Get the stack offset value.
4949 const MCExpr *StackOffset;
4950 int64_t StackOffsetVal;
4951 if (Parser.parseExpression(StackOffset)) {
4952 reportParseError("expected stack offset value");
4956 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4957 reportParseError("stack offset is not an absolute expression");
4961 if (StackOffsetVal < 0) {
4962 Warning(Loc, ".cprestore with negative stack offset has no effect");
4963 IsCpRestoreSet = false;
4965 IsCpRestoreSet = true;
4966 CpRestoreOffset = StackOffsetVal;
4969 // If this is not the end of the statement, report an error.
4970 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4971 reportParseError("unexpected token, expected end of statement");
4975 // Store the $gp on the stack.
4976 SmallVector<MCInst, 3> StoreInsts;
4977 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
4980 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
4981 Parser.Lex(); // Consume the EndOfStatement.
4985 bool MipsAsmParser::parseDirectiveCPSetup() {
4986 MCAsmParser &Parser = getParser();
4989 bool SaveIsReg = true;
4991 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4992 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4993 if (ResTy == MatchOperand_NoMatch) {
4994 reportParseError("expected register containing function address");
4995 Parser.eatToEndOfStatement();
4999 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5000 if (!FuncRegOpnd.isGPRAsmReg()) {
5001 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5002 Parser.eatToEndOfStatement();
5006 FuncReg = FuncRegOpnd.getGPR32Reg();
5009 if (!eatComma("unexpected token, expected comma"))
5012 ResTy = parseAnyRegister(TmpReg);
5013 if (ResTy == MatchOperand_NoMatch) {
5014 const MCExpr *OffsetExpr;
5016 SMLoc ExprLoc = getLexer().getLoc();
5018 if (Parser.parseExpression(OffsetExpr) ||
5019 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5020 reportParseError(ExprLoc, "expected save register or stack offset");
5021 Parser.eatToEndOfStatement();
5028 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5029 if (!SaveOpnd.isGPRAsmReg()) {
5030 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5031 Parser.eatToEndOfStatement();
5034 Save = SaveOpnd.getGPR32Reg();
5037 if (!eatComma("unexpected token, expected comma"))
5041 if (Parser.parseExpression(Expr)) {
5042 reportParseError("expected expression");
5046 if (Expr->getKind() != MCExpr::SymbolRef) {
5047 reportParseError("expected symbol");
5050 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5052 CpSaveLocation = Save;
5053 CpSaveLocationIsRegister = SaveIsReg;
5055 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5060 bool MipsAsmParser::parseDirectiveCPReturn() {
5061 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5062 CpSaveLocationIsRegister);
5066 bool MipsAsmParser::parseDirectiveNaN() {
5067 MCAsmParser &Parser = getParser();
5068 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5069 const AsmToken &Tok = Parser.getTok();
5071 if (Tok.getString() == "2008") {
5073 getTargetStreamer().emitDirectiveNaN2008();
5075 } else if (Tok.getString() == "legacy") {
5077 getTargetStreamer().emitDirectiveNaNLegacy();
5081 // If we don't recognize the option passed to the .nan
5082 // directive (e.g. no option or unknown option), emit an error.
5083 reportParseError("invalid option in .nan directive");
5087 bool MipsAsmParser::parseDirectiveSet() {
5088 MCAsmParser &Parser = getParser();
5089 // Get the next token.
5090 const AsmToken &Tok = Parser.getTok();
5092 if (Tok.getString() == "noat") {
5093 return parseSetNoAtDirective();
5094 } else if (Tok.getString() == "at") {
5095 return parseSetAtDirective();
5096 } else if (Tok.getString() == "arch") {
5097 return parseSetArchDirective();
5098 } else if (Tok.getString() == "fp") {
5099 return parseSetFpDirective();
5100 } else if (Tok.getString() == "oddspreg") {
5101 return parseSetOddSPRegDirective();
5102 } else if (Tok.getString() == "nooddspreg") {
5103 return parseSetNoOddSPRegDirective();
5104 } else if (Tok.getString() == "pop") {
5105 return parseSetPopDirective();
5106 } else if (Tok.getString() == "push") {
5107 return parseSetPushDirective();
5108 } else if (Tok.getString() == "reorder") {
5109 return parseSetReorderDirective();
5110 } else if (Tok.getString() == "noreorder") {
5111 return parseSetNoReorderDirective();
5112 } else if (Tok.getString() == "macro") {
5113 return parseSetMacroDirective();
5114 } else if (Tok.getString() == "nomacro") {
5115 return parseSetNoMacroDirective();
5116 } else if (Tok.getString() == "mips16") {
5117 return parseSetMips16Directive();
5118 } else if (Tok.getString() == "nomips16") {
5119 return parseSetNoMips16Directive();
5120 } else if (Tok.getString() == "nomicromips") {
5121 getTargetStreamer().emitDirectiveSetNoMicroMips();
5122 Parser.eatToEndOfStatement();
5124 } else if (Tok.getString() == "micromips") {
5125 return parseSetFeature(Mips::FeatureMicroMips);
5126 } else if (Tok.getString() == "mips0") {
5127 return parseSetMips0Directive();
5128 } else if (Tok.getString() == "mips1") {
5129 return parseSetFeature(Mips::FeatureMips1);
5130 } else if (Tok.getString() == "mips2") {
5131 return parseSetFeature(Mips::FeatureMips2);
5132 } else if (Tok.getString() == "mips3") {
5133 return parseSetFeature(Mips::FeatureMips3);
5134 } else if (Tok.getString() == "mips4") {
5135 return parseSetFeature(Mips::FeatureMips4);
5136 } else if (Tok.getString() == "mips5") {
5137 return parseSetFeature(Mips::FeatureMips5);
5138 } else if (Tok.getString() == "mips32") {
5139 return parseSetFeature(Mips::FeatureMips32);
5140 } else if (Tok.getString() == "mips32r2") {
5141 return parseSetFeature(Mips::FeatureMips32r2);
5142 } else if (Tok.getString() == "mips32r3") {
5143 return parseSetFeature(Mips::FeatureMips32r3);
5144 } else if (Tok.getString() == "mips32r5") {
5145 return parseSetFeature(Mips::FeatureMips32r5);
5146 } else if (Tok.getString() == "mips32r6") {
5147 return parseSetFeature(Mips::FeatureMips32r6);
5148 } else if (Tok.getString() == "mips64") {
5149 return parseSetFeature(Mips::FeatureMips64);
5150 } else if (Tok.getString() == "mips64r2") {
5151 return parseSetFeature(Mips::FeatureMips64r2);
5152 } else if (Tok.getString() == "mips64r3") {
5153 return parseSetFeature(Mips::FeatureMips64r3);
5154 } else if (Tok.getString() == "mips64r5") {
5155 return parseSetFeature(Mips::FeatureMips64r5);
5156 } else if (Tok.getString() == "mips64r6") {
5157 return parseSetFeature(Mips::FeatureMips64r6);
5158 } else if (Tok.getString() == "dsp") {
5159 return parseSetFeature(Mips::FeatureDSP);
5160 } else if (Tok.getString() == "nodsp") {
5161 return parseSetNoDspDirective();
5162 } else if (Tok.getString() == "msa") {
5163 return parseSetMsaDirective();
5164 } else if (Tok.getString() == "nomsa") {
5165 return parseSetNoMsaDirective();
5166 } else if (Tok.getString() == "softfloat") {
5167 return parseSetSoftFloatDirective();
5168 } else if (Tok.getString() == "hardfloat") {
5169 return parseSetHardFloatDirective();
5171 // It is just an identifier, look for an assignment.
5172 parseSetAssignment();
5179 /// parseDataDirective
5180 /// ::= .word [ expression (, expression)* ]
5181 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5182 MCAsmParser &Parser = getParser();
5183 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5185 const MCExpr *Value;
5186 if (getParser().parseExpression(Value))
5189 getParser().getStreamer().EmitValue(Value, Size);
5191 if (getLexer().is(AsmToken::EndOfStatement))
5194 if (getLexer().isNot(AsmToken::Comma))
5195 return Error(L, "unexpected token, expected comma");
5204 /// parseDirectiveGpWord
5205 /// ::= .gpword local_sym
5206 bool MipsAsmParser::parseDirectiveGpWord() {
5207 MCAsmParser &Parser = getParser();
5208 const MCExpr *Value;
5209 // EmitGPRel32Value requires an expression, so we are using base class
5210 // method to evaluate the expression.
5211 if (getParser().parseExpression(Value))
5213 getParser().getStreamer().EmitGPRel32Value(Value);
5215 if (getLexer().isNot(AsmToken::EndOfStatement))
5216 return Error(getLexer().getLoc(),
5217 "unexpected token, expected end of statement");
5218 Parser.Lex(); // Eat EndOfStatement token.
5222 /// parseDirectiveGpDWord
5223 /// ::= .gpdword local_sym
5224 bool MipsAsmParser::parseDirectiveGpDWord() {
5225 MCAsmParser &Parser = getParser();
5226 const MCExpr *Value;
5227 // EmitGPRel64Value requires an expression, so we are using base class
5228 // method to evaluate the expression.
5229 if (getParser().parseExpression(Value))
5231 getParser().getStreamer().EmitGPRel64Value(Value);
5233 if (getLexer().isNot(AsmToken::EndOfStatement))
5234 return Error(getLexer().getLoc(),
5235 "unexpected token, expected end of statement");
5236 Parser.Lex(); // Eat EndOfStatement token.
5240 bool MipsAsmParser::parseDirectiveOption() {
5241 MCAsmParser &Parser = getParser();
5242 // Get the option token.
5243 AsmToken Tok = Parser.getTok();
5244 // At the moment only identifiers are supported.
5245 if (Tok.isNot(AsmToken::Identifier)) {
5246 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5247 Parser.eatToEndOfStatement();
5251 StringRef Option = Tok.getIdentifier();
5253 if (Option == "pic0") {
5254 // MipsAsmParser needs to know if the current PIC mode changes.
5255 IsPicEnabled = false;
5257 getTargetStreamer().emitDirectiveOptionPic0();
5259 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5260 Error(Parser.getTok().getLoc(),
5261 "unexpected token, expected end of statement");
5262 Parser.eatToEndOfStatement();
5267 if (Option == "pic2") {
5268 // MipsAsmParser needs to know if the current PIC mode changes.
5269 IsPicEnabled = true;
5271 getTargetStreamer().emitDirectiveOptionPic2();
5273 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5274 Error(Parser.getTok().getLoc(),
5275 "unexpected token, expected end of statement");
5276 Parser.eatToEndOfStatement();
5282 Warning(Parser.getTok().getLoc(),
5283 "unknown option, expected 'pic0' or 'pic2'");
5284 Parser.eatToEndOfStatement();
5288 /// parseInsnDirective
5290 bool MipsAsmParser::parseInsnDirective() {
5291 // If this is not the end of the statement, report an error.
5292 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5293 reportParseError("unexpected token, expected end of statement");
5297 // The actual label marking happens in
5298 // MipsELFStreamer::createPendingLabelRelocs().
5299 getTargetStreamer().emitDirectiveInsn();
5301 getParser().Lex(); // Eat EndOfStatement token.
5305 /// parseDirectiveModule
5306 /// ::= .module oddspreg
5307 /// ::= .module nooddspreg
5308 /// ::= .module fp=value
5309 /// ::= .module softfloat
5310 /// ::= .module hardfloat
5311 bool MipsAsmParser::parseDirectiveModule() {
5312 MCAsmParser &Parser = getParser();
5313 MCAsmLexer &Lexer = getLexer();
5314 SMLoc L = Lexer.getLoc();
5316 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5317 // TODO : get a better message.
5318 reportParseError(".module directive must appear before any code");
5323 if (Parser.parseIdentifier(Option)) {
5324 reportParseError("expected .module option identifier");
5328 if (Option == "oddspreg") {
5329 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5331 // Synchronize the abiflags information with the FeatureBits information we
5333 getTargetStreamer().updateABIInfo(*this);
5335 // If printing assembly, use the recently updated abiflags information.
5336 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5337 // emitted at the end).
5338 getTargetStreamer().emitDirectiveModuleOddSPReg();
5340 // If this is not the end of the statement, report an error.
5341 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5342 reportParseError("unexpected token, expected end of statement");
5346 return false; // parseDirectiveModule has finished successfully.
5347 } else if (Option == "nooddspreg") {
5349 Error(L, "'.module nooddspreg' requires the O32 ABI");
5353 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5355 // Synchronize the abiflags information with the FeatureBits information we
5357 getTargetStreamer().updateABIInfo(*this);
5359 // If printing assembly, use the recently updated abiflags information.
5360 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5361 // emitted at the end).
5362 getTargetStreamer().emitDirectiveModuleOddSPReg();
5364 // If this is not the end of the statement, report an error.
5365 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5366 reportParseError("unexpected token, expected end of statement");
5370 return false; // parseDirectiveModule has finished successfully.
5371 } else if (Option == "fp") {
5372 return parseDirectiveModuleFP();
5373 } else if (Option == "softfloat") {
5374 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5376 // Synchronize the ABI Flags information with the FeatureBits information we
5378 getTargetStreamer().updateABIInfo(*this);
5380 // If printing assembly, use the recently updated ABI Flags information.
5381 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5383 getTargetStreamer().emitDirectiveModuleSoftFloat();
5385 // If this is not the end of the statement, report an error.
5386 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5387 reportParseError("unexpected token, expected end of statement");
5391 return false; // parseDirectiveModule has finished successfully.
5392 } else if (Option == "hardfloat") {
5393 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5395 // Synchronize the ABI Flags information with the FeatureBits information we
5397 getTargetStreamer().updateABIInfo(*this);
5399 // If printing assembly, use the recently updated ABI Flags information.
5400 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5402 getTargetStreamer().emitDirectiveModuleHardFloat();
5404 // If this is not the end of the statement, report an error.
5405 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5406 reportParseError("unexpected token, expected end of statement");
5410 return false; // parseDirectiveModule has finished successfully.
5412 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5416 /// parseDirectiveModuleFP
5420 bool MipsAsmParser::parseDirectiveModuleFP() {
5421 MCAsmParser &Parser = getParser();
5422 MCAsmLexer &Lexer = getLexer();
5424 if (Lexer.isNot(AsmToken::Equal)) {
5425 reportParseError("unexpected token, expected equals sign '='");
5428 Parser.Lex(); // Eat '=' token.
5430 MipsABIFlagsSection::FpABIKind FpABI;
5431 if (!parseFpABIValue(FpABI, ".module"))
5434 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5435 reportParseError("unexpected token, expected end of statement");
5439 // Synchronize the abiflags information with the FeatureBits information we
5441 getTargetStreamer().updateABIInfo(*this);
5443 // If printing assembly, use the recently updated abiflags information.
5444 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5445 // emitted at the end).
5446 getTargetStreamer().emitDirectiveModuleFP();
5448 Parser.Lex(); // Consume the EndOfStatement.
5452 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5453 StringRef Directive) {
5454 MCAsmParser &Parser = getParser();
5455 MCAsmLexer &Lexer = getLexer();
5456 bool ModuleLevelOptions = Directive == ".module";
5458 if (Lexer.is(AsmToken::Identifier)) {
5459 StringRef Value = Parser.getTok().getString();
5462 if (Value != "xx") {
5463 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5468 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5472 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5473 if (ModuleLevelOptions) {
5474 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5475 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5477 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5478 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5483 if (Lexer.is(AsmToken::Integer)) {
5484 unsigned Value = Parser.getTok().getIntVal();
5487 if (Value != 32 && Value != 64) {
5488 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5494 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5498 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5499 if (ModuleLevelOptions) {
5500 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5501 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5503 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5504 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5507 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5508 if (ModuleLevelOptions) {
5509 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5510 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5512 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5513 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5523 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5524 MCAsmParser &Parser = getParser();
5525 StringRef IDVal = DirectiveID.getString();
5527 if (IDVal == ".cpload")
5528 return parseDirectiveCpLoad(DirectiveID.getLoc());
5529 if (IDVal == ".cprestore")
5530 return parseDirectiveCpRestore(DirectiveID.getLoc());
5531 if (IDVal == ".dword") {
5532 parseDataDirective(8, DirectiveID.getLoc());
5535 if (IDVal == ".ent") {
5536 StringRef SymbolName;
5538 if (Parser.parseIdentifier(SymbolName)) {
5539 reportParseError("expected identifier after .ent");
5543 // There's an undocumented extension that allows an integer to
5544 // follow the name of the procedure which AFAICS is ignored by GAS.
5545 // Example: .ent foo,2
5546 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5547 if (getLexer().isNot(AsmToken::Comma)) {
5548 // Even though we accept this undocumented extension for compatibility
5549 // reasons, the additional integer argument does not actually change
5550 // the behaviour of the '.ent' directive, so we would like to discourage
5551 // its use. We do this by not referring to the extended version in
5552 // error messages which are not directly related to its use.
5553 reportParseError("unexpected token, expected end of statement");
5556 Parser.Lex(); // Eat the comma.
5557 const MCExpr *DummyNumber;
5558 int64_t DummyNumberVal;
5559 // If the user was explicitly trying to use the extended version,
5560 // we still give helpful extension-related error messages.
5561 if (Parser.parseExpression(DummyNumber)) {
5562 reportParseError("expected number after comma");
5565 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5566 reportParseError("expected an absolute expression after comma");
5571 // If this is not the end of the statement, report an error.
5572 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5573 reportParseError("unexpected token, expected end of statement");
5577 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5579 getTargetStreamer().emitDirectiveEnt(*Sym);
5581 IsCpRestoreSet = false;
5585 if (IDVal == ".end") {
5586 StringRef SymbolName;
5588 if (Parser.parseIdentifier(SymbolName)) {
5589 reportParseError("expected identifier after .end");
5593 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5594 reportParseError("unexpected token, expected end of statement");
5598 if (CurrentFn == nullptr) {
5599 reportParseError(".end used without .ent");
5603 if ((SymbolName != CurrentFn->getName())) {
5604 reportParseError(".end symbol does not match .ent symbol");
5608 getTargetStreamer().emitDirectiveEnd(SymbolName);
5609 CurrentFn = nullptr;
5610 IsCpRestoreSet = false;
5614 if (IDVal == ".frame") {
5615 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5616 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5617 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5618 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5619 reportParseError("expected stack register");
5623 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5624 if (!StackRegOpnd.isGPRAsmReg()) {
5625 reportParseError(StackRegOpnd.getStartLoc(),
5626 "expected general purpose register");
5629 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5631 if (Parser.getTok().is(AsmToken::Comma))
5634 reportParseError("unexpected token, expected comma");
5638 // Parse the frame size.
5639 const MCExpr *FrameSize;
5640 int64_t FrameSizeVal;
5642 if (Parser.parseExpression(FrameSize)) {
5643 reportParseError("expected frame size value");
5647 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5648 reportParseError("frame size not an absolute expression");
5652 if (Parser.getTok().is(AsmToken::Comma))
5655 reportParseError("unexpected token, expected comma");
5659 // Parse the return register.
5661 ResTy = parseAnyRegister(TmpReg);
5662 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5663 reportParseError("expected return register");
5667 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5668 if (!ReturnRegOpnd.isGPRAsmReg()) {
5669 reportParseError(ReturnRegOpnd.getStartLoc(),
5670 "expected general purpose register");
5674 // If this is not the end of the statement, report an error.
5675 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5676 reportParseError("unexpected token, expected end of statement");
5680 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5681 ReturnRegOpnd.getGPR32Reg());
5682 IsCpRestoreSet = false;
5686 if (IDVal == ".set") {
5687 return parseDirectiveSet();
5690 if (IDVal == ".mask" || IDVal == ".fmask") {
5691 // .mask bitmask, frame_offset
5692 // bitmask: One bit for each register used.
5693 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5694 // first register is expected to be saved.
5696 // .mask 0x80000000, -4
5697 // .fmask 0x80000000, -4
5700 // Parse the bitmask
5701 const MCExpr *BitMask;
5704 if (Parser.parseExpression(BitMask)) {
5705 reportParseError("expected bitmask value");
5709 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5710 reportParseError("bitmask not an absolute expression");
5714 if (Parser.getTok().is(AsmToken::Comma))
5717 reportParseError("unexpected token, expected comma");
5721 // Parse the frame_offset
5722 const MCExpr *FrameOffset;
5723 int64_t FrameOffsetVal;
5725 if (Parser.parseExpression(FrameOffset)) {
5726 reportParseError("expected frame offset value");
5730 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5731 reportParseError("frame offset not an absolute expression");
5735 // If this is not the end of the statement, report an error.
5736 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5737 reportParseError("unexpected token, expected end of statement");
5741 if (IDVal == ".mask")
5742 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5744 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5748 if (IDVal == ".nan")
5749 return parseDirectiveNaN();
5751 if (IDVal == ".gpword") {
5752 parseDirectiveGpWord();
5756 if (IDVal == ".gpdword") {
5757 parseDirectiveGpDWord();
5761 if (IDVal == ".word") {
5762 parseDataDirective(4, DirectiveID.getLoc());
5766 if (IDVal == ".option")
5767 return parseDirectiveOption();
5769 if (IDVal == ".abicalls") {
5770 getTargetStreamer().emitDirectiveAbiCalls();
5771 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5772 Error(Parser.getTok().getLoc(),
5773 "unexpected token, expected end of statement");
5775 Parser.eatToEndOfStatement();
5780 if (IDVal == ".cpsetup")
5781 return parseDirectiveCPSetup();
5783 if (IDVal == ".cpreturn")
5784 return parseDirectiveCPReturn();
5786 if (IDVal == ".module")
5787 return parseDirectiveModule();
5789 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5790 return parseInternalDirectiveReallowModule();
5792 if (IDVal == ".insn")
5793 return parseInsnDirective();
5798 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5799 // If this is not the end of the statement, report an error.
5800 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5801 reportParseError("unexpected token, expected end of statement");
5805 getTargetStreamer().reallowModuleDirective();
5807 getParser().Lex(); // Eat EndOfStatement token.
5811 extern "C" void LLVMInitializeMipsAsmParser() {
5812 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5813 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5814 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5815 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5818 #define GET_REGISTER_MATCHER
5819 #define GET_MATCHER_IMPLEMENTATION
5820 #include "MipsGenAsmMatcher.inc"