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'
120 // Print a warning along with its fix-it message at the given range.
121 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
122 SMRange Range, bool ShowColors = true);
124 #define GET_ASSEMBLER_HEADER
125 #include "MipsGenAsmMatcher.inc"
127 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
129 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
130 OperandVector &Operands, MCStreamer &Out,
132 bool MatchingInlineAsm) override;
134 /// Parse a register as used in CFI directives
135 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
137 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
139 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
141 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
142 SMLoc NameLoc, OperandVector &Operands) override;
144 bool ParseDirective(AsmToken DirectiveID) override;
146 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
148 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
149 StringRef Identifier, SMLoc S);
150 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
152 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
153 OperandMatchResultTy parseImm(OperandVector &Operands);
154 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
155 OperandMatchResultTy parseInvNum(OperandVector &Operands);
156 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
157 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
158 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
159 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
161 bool searchSymbolAlias(OperandVector &Operands);
163 bool parseOperand(OperandVector &, StringRef Mnemonic);
165 bool needsExpansion(MCInst &Inst);
167 // Expands assembly pseudo instructions.
168 // Returns false on success, true otherwise.
169 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
170 SmallVectorImpl<MCInst> &Instructions);
172 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
173 SmallVectorImpl<MCInst> &Instructions);
175 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
176 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
180 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
183 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
186 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
187 const MCOperand &Offset, bool Is32BitAddress,
188 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
190 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
197 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
203 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
207 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
210 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
211 SmallVectorImpl<MCInst> &Instructions);
213 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
214 SmallVectorImpl<MCInst> &Instructions);
216 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
217 SmallVectorImpl<MCInst> &Instructions);
219 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
220 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
222 bool reportParseError(Twine ErrorMsg);
223 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
225 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
226 bool parseRelocOperand(const MCExpr *&Res);
228 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
230 bool isEvaluated(const MCExpr *Expr);
231 bool parseSetMips0Directive();
232 bool parseSetArchDirective();
233 bool parseSetFeature(uint64_t Feature);
234 bool parseDirectiveCpLoad(SMLoc Loc);
235 bool parseDirectiveCPSetup();
236 bool parseDirectiveNaN();
237 bool parseDirectiveSet();
238 bool parseDirectiveOption();
239 bool parseInsnDirective();
241 bool parseSetAtDirective();
242 bool parseSetNoAtDirective();
243 bool parseSetMacroDirective();
244 bool parseSetNoMacroDirective();
245 bool parseSetMsaDirective();
246 bool parseSetNoMsaDirective();
247 bool parseSetNoDspDirective();
248 bool parseSetReorderDirective();
249 bool parseSetNoReorderDirective();
250 bool parseSetMips16Directive();
251 bool parseSetNoMips16Directive();
252 bool parseSetFpDirective();
253 bool parseSetOddSPRegDirective();
254 bool parseSetNoOddSPRegDirective();
255 bool parseSetPopDirective();
256 bool parseSetPushDirective();
257 bool parseSetSoftFloatDirective();
258 bool parseSetHardFloatDirective();
260 bool parseSetAssignment();
262 bool parseDataDirective(unsigned Size, SMLoc L);
263 bool parseDirectiveGpWord();
264 bool parseDirectiveGpDWord();
265 bool parseDirectiveModule();
266 bool parseDirectiveModuleFP();
267 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
268 StringRef Directive);
270 bool parseInternalDirectiveReallowModule();
272 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
274 bool eatComma(StringRef ErrorStr);
276 int matchCPURegisterName(StringRef Symbol);
278 int matchHWRegsRegisterName(StringRef Symbol);
280 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
282 int matchFPURegisterName(StringRef Name);
284 int matchFCCRegisterName(StringRef Name);
286 int matchACRegisterName(StringRef Name);
288 int matchMSA128RegisterName(StringRef Name);
290 int matchMSA128CtrlRegisterName(StringRef Name);
292 unsigned getReg(int RC, int RegNo);
294 unsigned getGPR(int RegNo);
296 /// Returns the internal register number for the current AT. Also checks if
297 /// the current AT is unavailable (set to $0) and gives an error if it is.
298 /// This should be used in pseudo-instruction expansions which need AT.
299 unsigned getATReg(SMLoc Loc);
301 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
302 SmallVectorImpl<MCInst> &Instructions);
304 // Helper function that checks if the value of a vector index is within the
305 // boundaries of accepted values for each RegisterKind
306 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
307 bool validateMSAIndex(int Val, int RegKind);
309 // Selects a new architecture by updating the FeatureBits with the necessary
310 // info including implied dependencies.
311 // Internally, it clears all the feature bits related to *any* architecture
312 // and selects the new one using the ToggleFeature functionality of the
313 // MCSubtargetInfo object that handles implied dependencies. The reason we
314 // clear all the arch related bits manually is because ToggleFeature only
315 // clears the features that imply the feature being cleared and not the
316 // features implied by the feature being cleared. This is easier to see
318 // --------------------------------------------------
319 // | Feature | Implies |
320 // | -------------------------------------------------|
321 // | FeatureMips1 | None |
322 // | FeatureMips2 | FeatureMips1 |
323 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
324 // | FeatureMips4 | FeatureMips3 |
326 // --------------------------------------------------
328 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
329 // FeatureMipsGP64 | FeatureMips1)
330 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
331 void selectArch(StringRef ArchFeature) {
332 FeatureBitset FeatureBits = STI.getFeatureBits();
333 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
334 STI.setFeatureBits(FeatureBits);
335 setAvailableFeatures(
336 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
337 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
340 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
341 if (!(STI.getFeatureBits()[Feature])) {
342 setAvailableFeatures(
343 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
344 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
348 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
349 if (STI.getFeatureBits()[Feature]) {
350 setAvailableFeatures(
351 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
352 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
356 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
357 setFeatureBits(Feature, FeatureString);
358 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
361 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
362 clearFeatureBits(Feature, FeatureString);
363 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
367 enum MipsMatchResultTy {
368 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
369 #define GET_OPERAND_DIAGNOSTIC_TYPES
370 #include "MipsGenAsmMatcher.inc"
371 #undef GET_OPERAND_DIAGNOSTIC_TYPES
375 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
376 const MCInstrInfo &MII, const MCTargetOptions &Options)
377 : MCTargetAsmParser(Options), STI(sti),
378 ABI(MipsABIInfo::computeTargetABI(sti.getTargetTuple(), sti.getCPU(),
380 MCAsmParserExtension::Initialize(parser);
382 parser.addAliasForDirective(".asciiz", ".asciz");
384 // Initialize the set of available features.
385 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
387 // Remember the initial assembler options. The user can not modify these.
388 AssemblerOptions.push_back(
389 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
391 // Create an assembler options environment for the user to modify.
392 AssemblerOptions.push_back(
393 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
395 getTargetStreamer().updateABIInfo(*this);
397 if (!isABI_O32() && !useOddSPReg() != 0)
398 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
403 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
405 const TargetTuple &TT = sti.getTargetTuple();
406 if ((TT.getArch() == TargetTuple::mips) ||
407 (TT.getArch() == TargetTuple::mips64))
408 IsLittleEndian = false;
410 IsLittleEndian = true;
413 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
414 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
416 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
417 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
418 const MipsABIInfo &getABI() const { return ABI; }
419 bool isABI_N32() const { return ABI.IsN32(); }
420 bool isABI_N64() const { return ABI.IsN64(); }
421 bool isABI_O32() const { return ABI.IsO32(); }
422 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
424 bool useOddSPReg() const {
425 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
428 bool inMicroMipsMode() const {
429 return STI.getFeatureBits()[Mips::FeatureMicroMips];
431 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
432 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
433 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
434 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
435 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
436 bool hasMips32() const {
437 return STI.getFeatureBits()[Mips::FeatureMips32];
439 bool hasMips64() const {
440 return STI.getFeatureBits()[Mips::FeatureMips64];
442 bool hasMips32r2() const {
443 return STI.getFeatureBits()[Mips::FeatureMips32r2];
445 bool hasMips64r2() const {
446 return STI.getFeatureBits()[Mips::FeatureMips64r2];
448 bool hasMips32r3() const {
449 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
451 bool hasMips64r3() const {
452 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
454 bool hasMips32r5() const {
455 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
457 bool hasMips64r5() const {
458 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
460 bool hasMips32r6() const {
461 return STI.getFeatureBits()[Mips::FeatureMips32r6];
463 bool hasMips64r6() const {
464 return STI.getFeatureBits()[Mips::FeatureMips64r6];
467 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
468 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
469 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
470 bool hasCnMips() const {
471 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
478 bool inMips16Mode() const {
479 return STI.getFeatureBits()[Mips::FeatureMips16];
482 bool useTraps() const {
483 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
486 bool useSoftFloat() const {
487 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
490 /// Warn if RegIndex is the same as the current AT.
491 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
493 void warnIfNoMacro(SMLoc Loc);
495 bool isLittle() const { return IsLittleEndian; }
501 /// MipsOperand - Instances of this class represent a parsed Mips machine
503 class MipsOperand : public MCParsedAsmOperand {
505 /// Broad categories of register classes
506 /// The exact class is finalized by the render method.
508 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
509 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
511 RegKind_FCC = 4, /// FCC
512 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
513 RegKind_MSACtrl = 16, /// MSA control registers
514 RegKind_COP2 = 32, /// COP2
515 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
517 RegKind_CCR = 128, /// CCR
518 RegKind_HWRegs = 256, /// HWRegs
519 RegKind_COP3 = 512, /// COP3
520 RegKind_COP0 = 1024, /// COP0
521 /// Potentially any (e.g. $1)
522 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
523 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
524 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
529 k_Immediate, /// An immediate (possibly involving symbol references)
530 k_Memory, /// Base + Offset Memory Address
531 k_PhysRegister, /// A physical register from the Mips namespace
532 k_RegisterIndex, /// A register index in one or more RegKind.
533 k_Token, /// A simple token
534 k_RegList, /// A physical register list
535 k_RegPair /// A pair of physical register
539 MipsOperand(KindTy K, MipsAsmParser &Parser)
540 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
543 /// For diagnostics, and checking the assembler temporary
544 MipsAsmParser &AsmParser;
552 unsigned Num; /// Register Number
556 unsigned Index; /// Index into the register class
557 RegKind Kind; /// Bitfield of the kinds it could possibly be
558 const MCRegisterInfo *RegInfo;
571 SmallVector<unsigned, 10> *List;
576 struct PhysRegOp PhysReg;
577 struct RegIdxOp RegIdx;
580 struct RegListOp RegList;
583 SMLoc StartLoc, EndLoc;
585 /// Internal constructor for register kinds
586 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
587 const MCRegisterInfo *RegInfo,
589 MipsAsmParser &Parser) {
590 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
591 Op->RegIdx.Index = Index;
592 Op->RegIdx.RegInfo = RegInfo;
593 Op->RegIdx.Kind = RegKind;
600 /// Coerce the register to GPR32 and return the real register for the current
602 unsigned getGPR32Reg() const {
603 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
604 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
605 unsigned ClassID = Mips::GPR32RegClassID;
606 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
609 /// Coerce the register to GPR32 and return the real register for the current
611 unsigned getGPRMM16Reg() const {
612 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
613 unsigned ClassID = Mips::GPR32RegClassID;
614 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
617 /// Coerce the register to GPR64 and return the real register for the current
619 unsigned getGPR64Reg() const {
620 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
621 unsigned ClassID = Mips::GPR64RegClassID;
622 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
626 /// Coerce the register to AFGR64 and return the real register for the current
628 unsigned getAFGR64Reg() const {
629 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
630 if (RegIdx.Index % 2 != 0)
631 AsmParser.Warning(StartLoc, "Float register should be even.");
632 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
633 .getRegister(RegIdx.Index / 2);
636 /// Coerce the register to FGR64 and return the real register for the current
638 unsigned getFGR64Reg() const {
639 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
640 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
641 .getRegister(RegIdx.Index);
644 /// Coerce the register to FGR32 and return the real register for the current
646 unsigned getFGR32Reg() const {
647 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
648 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
649 .getRegister(RegIdx.Index);
652 /// Coerce the register to FGRH32 and return the real register for the current
654 unsigned getFGRH32Reg() const {
655 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
656 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
657 .getRegister(RegIdx.Index);
660 /// Coerce the register to FCC and return the real register for the current
662 unsigned getFCCReg() const {
663 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
664 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
665 .getRegister(RegIdx.Index);
668 /// Coerce the register to MSA128 and return the real register for the current
670 unsigned getMSA128Reg() const {
671 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
672 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
674 unsigned ClassID = Mips::MSA128BRegClassID;
675 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
678 /// Coerce the register to MSACtrl and return the real register for the
680 unsigned getMSACtrlReg() const {
681 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
682 unsigned ClassID = Mips::MSACtrlRegClassID;
683 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
686 /// Coerce the register to COP0 and return the real register for the
688 unsigned getCOP0Reg() const {
689 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
690 unsigned ClassID = Mips::COP0RegClassID;
691 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
694 /// Coerce the register to COP2 and return the real register for the
696 unsigned getCOP2Reg() const {
697 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
698 unsigned ClassID = Mips::COP2RegClassID;
699 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
702 /// Coerce the register to COP3 and return the real register for the
704 unsigned getCOP3Reg() const {
705 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
706 unsigned ClassID = Mips::COP3RegClassID;
707 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
710 /// Coerce the register to ACC64DSP and return the real register for the
712 unsigned getACC64DSPReg() const {
713 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
714 unsigned ClassID = Mips::ACC64DSPRegClassID;
715 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
718 /// Coerce the register to HI32DSP and return the real register for the
720 unsigned getHI32DSPReg() const {
721 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
722 unsigned ClassID = Mips::HI32DSPRegClassID;
723 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
726 /// Coerce the register to LO32DSP and return the real register for the
728 unsigned getLO32DSPReg() const {
729 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
730 unsigned ClassID = Mips::LO32DSPRegClassID;
731 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
734 /// Coerce the register to CCR and return the real register for the
736 unsigned getCCRReg() const {
737 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
738 unsigned ClassID = Mips::CCRRegClassID;
739 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
742 /// Coerce the register to HWRegs and return the real register for the
744 unsigned getHWRegsReg() const {
745 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
746 unsigned ClassID = Mips::HWRegsRegClassID;
747 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
751 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
752 // Add as immediate when possible. Null MCExpr = 0.
754 Inst.addOperand(MCOperand::createImm(0));
755 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
756 Inst.addOperand(MCOperand::createImm(CE->getValue()));
758 Inst.addOperand(MCOperand::createExpr(Expr));
761 void addRegOperands(MCInst &Inst, unsigned N) const {
762 llvm_unreachable("Use a custom parser instead");
765 /// Render the operand to an MCInst as a GPR32
766 /// Asserts if the wrong number of operands are requested, or the operand
767 /// is not a k_RegisterIndex compatible with RegKind_GPR
768 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
769 assert(N == 1 && "Invalid number of operands!");
770 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
773 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
774 assert(N == 1 && "Invalid number of operands!");
775 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
778 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
783 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
788 /// Render the operand to an MCInst as a GPR64
789 /// Asserts if the wrong number of operands are requested, or the operand
790 /// is not a k_RegisterIndex compatible with RegKind_GPR
791 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
792 assert(N == 1 && "Invalid number of operands!");
793 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
796 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
797 assert(N == 1 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
801 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
802 assert(N == 1 && "Invalid number of operands!");
803 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
806 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
807 assert(N == 1 && "Invalid number of operands!");
808 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
809 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
810 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
811 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
815 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
816 assert(N == 1 && "Invalid number of operands!");
817 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
820 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
821 assert(N == 1 && "Invalid number of operands!");
822 Inst.addOperand(MCOperand::createReg(getFCCReg()));
825 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
826 assert(N == 1 && "Invalid number of operands!");
827 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
830 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
831 assert(N == 1 && "Invalid number of operands!");
832 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
835 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
836 assert(N == 1 && "Invalid number of operands!");
837 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
840 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 1 && "Invalid number of operands!");
842 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
845 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
846 assert(N == 1 && "Invalid number of operands!");
847 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
850 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
851 assert(N == 1 && "Invalid number of operands!");
852 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
855 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
856 assert(N == 1 && "Invalid number of operands!");
857 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
860 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
861 assert(N == 1 && "Invalid number of operands!");
862 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
865 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
866 assert(N == 1 && "Invalid number of operands!");
867 Inst.addOperand(MCOperand::createReg(getCCRReg()));
870 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
871 assert(N == 1 && "Invalid number of operands!");
872 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
875 void addImmOperands(MCInst &Inst, unsigned N) const {
876 assert(N == 1 && "Invalid number of operands!");
877 const MCExpr *Expr = getImm();
881 void addMemOperands(MCInst &Inst, unsigned N) const {
882 assert(N == 2 && "Invalid number of operands!");
884 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
885 ? getMemBase()->getGPR64Reg()
886 : getMemBase()->getGPR32Reg()));
888 const MCExpr *Expr = getMemOff();
892 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
893 assert(N == 2 && "Invalid number of operands!");
895 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
897 const MCExpr *Expr = getMemOff();
901 void addRegListOperands(MCInst &Inst, unsigned N) const {
902 assert(N == 1 && "Invalid number of operands!");
904 for (auto RegNo : getRegList())
905 Inst.addOperand(MCOperand::createReg(RegNo));
908 void addRegPairOperands(MCInst &Inst, unsigned N) const {
909 assert(N == 2 && "Invalid number of operands!");
910 unsigned RegNo = getRegPair();
911 Inst.addOperand(MCOperand::createReg(RegNo++));
912 Inst.addOperand(MCOperand::createReg(RegNo));
915 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
916 assert(N == 2 && "Invalid number of operands!");
917 for (auto RegNo : getRegList())
918 Inst.addOperand(MCOperand::createReg(RegNo));
921 bool isReg() const override {
922 // As a special case until we sort out the definition of div/divu, pretend
923 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
924 if (isGPRAsmReg() && RegIdx.Index == 0)
927 return Kind == k_PhysRegister;
929 bool isRegIdx() const { return Kind == k_RegisterIndex; }
930 bool isImm() const override { return Kind == k_Immediate; }
931 bool isConstantImm() const {
932 return isImm() && dyn_cast<MCConstantExpr>(getImm());
934 template <unsigned Bits> bool isUImm() const {
935 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
937 bool isToken() const override {
938 // Note: It's not possible to pretend that other operand kinds are tokens.
939 // The matcher emitter checks tokens first.
940 return Kind == k_Token;
942 bool isMem() const override { return Kind == k_Memory; }
943 bool isConstantMemOff() const {
944 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
946 template <unsigned Bits> bool isMemWithSimmOffset() const {
947 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
948 && getMemBase()->isGPRAsmReg();
950 bool isMemWithGRPMM16Base() const {
951 return isMem() && getMemBase()->isMM16AsmReg();
953 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
954 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
955 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
957 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
958 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
959 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
960 && (getMemBase()->getGPR32Reg() == Mips::SP);
962 bool isRegList16() const {
966 int Size = RegList.List->size();
967 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
968 RegList.List->back() != Mips::RA)
971 int PrevReg = *RegList.List->begin();
972 for (int i = 1; i < Size - 1; i++) {
973 int Reg = (*(RegList.List))[i];
974 if ( Reg != PrevReg + 1)
981 bool isInvNum() const { return Kind == k_Immediate; }
982 bool isLSAImm() const {
983 if (!isConstantImm())
985 int64_t Val = getConstantImm();
986 return 1 <= Val && Val <= 4;
988 bool isRegList() const { return Kind == k_RegList; }
989 bool isMovePRegPair() const {
990 if (Kind != k_RegList || RegList.List->size() != 2)
993 unsigned R0 = RegList.List->front();
994 unsigned R1 = RegList.List->back();
996 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
997 (R0 == Mips::A1 && R1 == Mips::A3) ||
998 (R0 == Mips::A2 && R1 == Mips::A3) ||
999 (R0 == Mips::A0 && R1 == Mips::S5) ||
1000 (R0 == Mips::A0 && R1 == Mips::S6) ||
1001 (R0 == Mips::A0 && R1 == Mips::A1) ||
1002 (R0 == Mips::A0 && R1 == Mips::A2) ||
1003 (R0 == Mips::A0 && R1 == Mips::A3))
1009 StringRef getToken() const {
1010 assert(Kind == k_Token && "Invalid access!");
1011 return StringRef(Tok.Data, Tok.Length);
1013 bool isRegPair() const { return Kind == k_RegPair; }
1015 unsigned getReg() const override {
1016 // As a special case until we sort out the definition of div/divu, pretend
1017 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1018 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1019 RegIdx.Kind & RegKind_GPR)
1020 return getGPR32Reg(); // FIXME: GPR64 too
1022 assert(Kind == k_PhysRegister && "Invalid access!");
1026 const MCExpr *getImm() const {
1027 assert((Kind == k_Immediate) && "Invalid access!");
1031 int64_t getConstantImm() const {
1032 const MCExpr *Val = getImm();
1033 return static_cast<const MCConstantExpr *>(Val)->getValue();
1036 MipsOperand *getMemBase() const {
1037 assert((Kind == k_Memory) && "Invalid access!");
1041 const MCExpr *getMemOff() const {
1042 assert((Kind == k_Memory) && "Invalid access!");
1046 int64_t getConstantMemOff() const {
1047 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1050 const SmallVectorImpl<unsigned> &getRegList() const {
1051 assert((Kind == k_RegList) && "Invalid access!");
1052 return *(RegList.List);
1055 unsigned getRegPair() const {
1056 assert((Kind == k_RegPair) && "Invalid access!");
1057 return RegIdx.Index;
1060 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1061 MipsAsmParser &Parser) {
1062 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1063 Op->Tok.Data = Str.data();
1064 Op->Tok.Length = Str.size();
1070 /// Create a numeric register (e.g. $1). The exact register remains
1071 /// unresolved until an instruction successfully matches
1072 static std::unique_ptr<MipsOperand>
1073 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1074 SMLoc E, MipsAsmParser &Parser) {
1075 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1076 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1079 /// Create a register that is definitely a GPR.
1080 /// This is typically only used for named registers such as $gp.
1081 static std::unique_ptr<MipsOperand>
1082 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1083 MipsAsmParser &Parser) {
1084 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1087 /// Create a register that is definitely a FGR.
1088 /// This is typically only used for named registers such as $f0.
1089 static std::unique_ptr<MipsOperand>
1090 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1091 MipsAsmParser &Parser) {
1092 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1095 /// Create a register that is definitely a HWReg.
1096 /// This is typically only used for named registers such as $hwr_cpunum.
1097 static std::unique_ptr<MipsOperand>
1098 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1099 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1100 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1103 /// Create a register that is definitely an FCC.
1104 /// This is typically only used for named registers such as $fcc0.
1105 static std::unique_ptr<MipsOperand>
1106 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1107 MipsAsmParser &Parser) {
1108 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1111 /// Create a register that is definitely an ACC.
1112 /// This is typically only used for named registers such as $ac0.
1113 static std::unique_ptr<MipsOperand>
1114 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1115 MipsAsmParser &Parser) {
1116 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1119 /// Create a register that is definitely an MSA128.
1120 /// This is typically only used for named registers such as $w0.
1121 static std::unique_ptr<MipsOperand>
1122 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1123 SMLoc E, MipsAsmParser &Parser) {
1124 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1127 /// Create a register that is definitely an MSACtrl.
1128 /// This is typically only used for named registers such as $msaaccess.
1129 static std::unique_ptr<MipsOperand>
1130 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1131 SMLoc E, MipsAsmParser &Parser) {
1132 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1135 static std::unique_ptr<MipsOperand>
1136 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1137 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1144 static std::unique_ptr<MipsOperand>
1145 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1146 SMLoc E, MipsAsmParser &Parser) {
1147 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1148 Op->Mem.Base = Base.release();
1155 static std::unique_ptr<MipsOperand>
1156 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1157 MipsAsmParser &Parser) {
1158 assert (Regs.size() > 0 && "Empty list not allowed");
1160 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1161 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1162 Op->StartLoc = StartLoc;
1163 Op->EndLoc = EndLoc;
1167 static std::unique_ptr<MipsOperand>
1168 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1169 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1170 Op->RegIdx.Index = RegNo;
1176 bool isGPRAsmReg() const {
1177 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1179 bool isMM16AsmReg() const {
1180 if (!(isRegIdx() && RegIdx.Kind))
1182 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1183 || RegIdx.Index == 16 || RegIdx.Index == 17);
1185 bool isMM16AsmRegZero() const {
1186 if (!(isRegIdx() && RegIdx.Kind))
1188 return (RegIdx.Index == 0 ||
1189 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1190 RegIdx.Index == 17);
1192 bool isMM16AsmRegMoveP() const {
1193 if (!(isRegIdx() && RegIdx.Kind))
1195 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1196 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1198 bool isFGRAsmReg() const {
1199 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1200 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1202 bool isHWRegsAsmReg() const {
1203 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1205 bool isCCRAsmReg() const {
1206 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1208 bool isFCCAsmReg() const {
1209 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1211 if (!AsmParser.hasEightFccRegisters())
1212 return RegIdx.Index == 0;
1213 return RegIdx.Index <= 7;
1215 bool isACCAsmReg() const {
1216 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1218 bool isCOP0AsmReg() const {
1219 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1221 bool isCOP2AsmReg() const {
1222 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1224 bool isCOP3AsmReg() const {
1225 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1227 bool isMSA128AsmReg() const {
1228 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1230 bool isMSACtrlAsmReg() const {
1231 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1234 /// getStartLoc - Get the location of the first token of this operand.
1235 SMLoc getStartLoc() const override { return StartLoc; }
1236 /// getEndLoc - Get the location of the last token of this operand.
1237 SMLoc getEndLoc() const override { return EndLoc; }
1239 virtual ~MipsOperand() {
1247 delete RegList.List;
1248 case k_PhysRegister:
1249 case k_RegisterIndex:
1256 void print(raw_ostream &OS) const override {
1265 Mem.Base->print(OS);
1270 case k_PhysRegister:
1271 OS << "PhysReg<" << PhysReg.Num << ">";
1273 case k_RegisterIndex:
1274 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1281 for (auto Reg : (*RegList.List))
1286 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1290 }; // class MipsOperand
1294 extern const MCInstrDesc MipsInsts[];
1296 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1297 return MipsInsts[Opcode];
1300 static bool hasShortDelaySlot(unsigned Opcode) {
1303 case Mips::JALRS_MM:
1304 case Mips::JALRS16_MM:
1305 case Mips::BGEZALS_MM:
1306 case Mips::BLTZALS_MM:
1313 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1314 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1315 return &SRExpr->getSymbol();
1318 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1319 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1320 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1331 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1332 return getSingleMCSymbol(UExpr->getSubExpr());
1337 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1338 if (isa<MCSymbolRefExpr>(Expr))
1341 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1342 return countMCSymbolRefExpr(BExpr->getLHS()) +
1343 countMCSymbolRefExpr(BExpr->getRHS());
1345 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1346 return countMCSymbolRefExpr(UExpr->getSubExpr());
1351 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1352 SmallVectorImpl<MCInst> &Instructions) {
1353 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1357 if (MCID.isBranch() || MCID.isCall()) {
1358 const unsigned Opcode = Inst.getOpcode();
1368 assert(hasCnMips() && "instruction only valid for octeon cpus");
1375 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1376 Offset = Inst.getOperand(2);
1377 if (!Offset.isImm())
1378 break; // We'll deal with this situation later on when applying fixups.
1379 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1380 return Error(IDLoc, "branch target out of range");
1381 if (OffsetToAlignment(Offset.getImm(),
1382 1LL << (inMicroMipsMode() ? 1 : 2)))
1383 return Error(IDLoc, "branch to misaligned address");
1397 case Mips::BGEZAL_MM:
1398 case Mips::BLTZAL_MM:
1401 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1402 Offset = Inst.getOperand(1);
1403 if (!Offset.isImm())
1404 break; // We'll deal with this situation later on when applying fixups.
1405 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1406 return Error(IDLoc, "branch target out of range");
1407 if (OffsetToAlignment(Offset.getImm(),
1408 1LL << (inMicroMipsMode() ? 1 : 2)))
1409 return Error(IDLoc, "branch to misaligned address");
1411 case Mips::BEQZ16_MM:
1412 case Mips::BEQZC16_MMR6:
1413 case Mips::BNEZ16_MM:
1414 case Mips::BNEZC16_MMR6:
1415 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1416 Offset = Inst.getOperand(1);
1417 if (!Offset.isImm())
1418 break; // We'll deal with this situation later on when applying fixups.
1419 if (!isIntN(8, Offset.getImm()))
1420 return Error(IDLoc, "branch target out of range");
1421 if (OffsetToAlignment(Offset.getImm(), 2LL))
1422 return Error(IDLoc, "branch to misaligned address");
1427 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1428 // We still accept it but it is a normal nop.
1429 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1430 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1431 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1436 const unsigned Opcode = Inst.getOpcode();
1448 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1449 // The offset is handled above
1450 Opnd = Inst.getOperand(1);
1452 return Error(IDLoc, "expected immediate operand kind");
1453 Imm = Opnd.getImm();
1454 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1455 Opcode == Mips::BBIT1 ? 63 : 31))
1456 return Error(IDLoc, "immediate operand value out of range");
1458 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1460 Inst.getOperand(1).setImm(Imm - 32);
1468 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1470 Opnd = Inst.getOperand(3);
1472 return Error(IDLoc, "expected immediate operand kind");
1473 Imm = Opnd.getImm();
1474 if (Imm < 0 || Imm > 31)
1475 return Error(IDLoc, "immediate operand value out of range");
1477 Opnd = Inst.getOperand(2);
1479 return Error(IDLoc, "expected immediate operand kind");
1480 Imm = Opnd.getImm();
1481 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1482 Opcode == Mips::EXTS ? 63 : 31))
1483 return Error(IDLoc, "immediate operand value out of range");
1485 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1486 Inst.getOperand(2).setImm(Imm - 32);
1492 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1493 Opnd = Inst.getOperand(2);
1495 return Error(IDLoc, "expected immediate operand kind");
1496 Imm = Opnd.getImm();
1497 if (!isInt<10>(Imm))
1498 return Error(IDLoc, "immediate operand value out of range");
1503 // This expansion is not in a function called by expandInstruction() because
1504 // the pseudo-instruction doesn't have a distinct opcode.
1505 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1507 warnIfNoMacro(IDLoc);
1509 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1511 // We can do this expansion if there's only 1 symbol in the argument
1513 if (countMCSymbolRefExpr(JalExpr) > 1)
1514 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1516 // FIXME: This is checking the expression can be handled by the later stages
1517 // of the assembler. We ought to leave it to those later stages but
1518 // we can't do that until we stop evaluateRelocExpr() rewriting the
1519 // expressions into non-equivalent forms.
1520 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1522 // FIXME: Add support for label+offset operands (currently causes an error).
1523 // FIXME: Add support for forward-declared local symbols.
1524 // FIXME: Add expansion for when the LargeGOT option is enabled.
1525 if (JalSym->isInSection() || JalSym->isTemporary()) {
1527 // If it's a local symbol and the O32 ABI is being used, we expand to:
1529 // R_(MICRO)MIPS_GOT16 label
1530 // addiu $25, $25, 0
1531 // R_(MICRO)MIPS_LO16 label
1533 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1534 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1537 LwInst.setOpcode(Mips::LW);
1538 LwInst.addOperand(MCOperand::createReg(Mips::T9));
1539 LwInst.addOperand(MCOperand::createReg(Mips::GP));
1540 LwInst.addOperand(MCOperand::createExpr(Got16RelocExpr));
1541 Instructions.push_back(LwInst);
1544 AddiuInst.setOpcode(Mips::ADDiu);
1545 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1546 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1547 AddiuInst.addOperand(MCOperand::createExpr(Lo16RelocExpr));
1548 Instructions.push_back(AddiuInst);
1549 } else if (isABI_N32() || isABI_N64()) {
1550 // If it's a local symbol and the N32/N64 ABIs are being used,
1552 // lw/ld $25, 0($gp)
1553 // R_(MICRO)MIPS_GOT_DISP label
1555 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1558 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1559 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1560 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1561 LoadInst.addOperand(MCOperand::createExpr(GotDispRelocExpr));
1562 Instructions.push_back(LoadInst);
1565 // If it's an external/weak symbol, we expand to:
1566 // lw/ld $25, 0($gp)
1567 // R_(MICRO)MIPS_CALL16 label
1569 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1572 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1573 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1574 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1575 LoadInst.addOperand(MCOperand::createExpr(Call16RelocExpr));
1576 Instructions.push_back(LoadInst);
1580 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1581 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1582 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1584 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1585 // This relocation is supposed to be an optimization hint for the linker
1586 // and is not necessary for correctness.
1591 if (MCID.mayLoad() || MCID.mayStore()) {
1592 // Check the offset of memory operand, if it is a symbol
1593 // reference or immediate we may have to expand instructions.
1594 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1595 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1596 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1597 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1598 MCOperand &Op = Inst.getOperand(i);
1600 int MemOffset = Op.getImm();
1601 if (MemOffset < -32768 || MemOffset > 32767) {
1602 // Offset can't exceed 16bit value.
1603 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1606 } else if (Op.isExpr()) {
1607 const MCExpr *Expr = Op.getExpr();
1608 if (Expr->getKind() == MCExpr::SymbolRef) {
1609 const MCSymbolRefExpr *SR =
1610 static_cast<const MCSymbolRefExpr *>(Expr);
1611 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1613 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1616 } else if (!isEvaluated(Expr)) {
1617 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1625 if (inMicroMipsMode()) {
1626 if (MCID.mayLoad()) {
1627 // Try to create 16-bit GP relative load instruction.
1628 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1629 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1630 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1631 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1632 MCOperand &Op = Inst.getOperand(i);
1634 int MemOffset = Op.getImm();
1635 MCOperand &DstReg = Inst.getOperand(0);
1636 MCOperand &BaseReg = Inst.getOperand(1);
1637 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1638 getContext().getRegisterInfo()->getRegClass(
1639 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1640 (BaseReg.getReg() == Mips::GP ||
1641 BaseReg.getReg() == Mips::GP_64)) {
1643 TmpInst.setLoc(IDLoc);
1644 TmpInst.setOpcode(Mips::LWGP_MM);
1645 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1646 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1647 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1648 Instructions.push_back(TmpInst);
1656 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1661 switch (Inst.getOpcode()) {
1664 case Mips::ADDIUS5_MM:
1665 Opnd = Inst.getOperand(2);
1667 return Error(IDLoc, "expected immediate operand kind");
1668 Imm = Opnd.getImm();
1669 if (Imm < -8 || Imm > 7)
1670 return Error(IDLoc, "immediate operand value out of range");
1672 case Mips::ADDIUSP_MM:
1673 Opnd = Inst.getOperand(0);
1675 return Error(IDLoc, "expected immediate operand kind");
1676 Imm = Opnd.getImm();
1677 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1679 return Error(IDLoc, "immediate operand value out of range");
1681 case Mips::SLL16_MM:
1682 case Mips::SRL16_MM:
1683 Opnd = Inst.getOperand(2);
1685 return Error(IDLoc, "expected immediate operand kind");
1686 Imm = Opnd.getImm();
1687 if (Imm < 1 || Imm > 8)
1688 return Error(IDLoc, "immediate operand value out of range");
1691 Opnd = Inst.getOperand(1);
1693 return Error(IDLoc, "expected immediate operand kind");
1694 Imm = Opnd.getImm();
1695 if (Imm < -1 || Imm > 126)
1696 return Error(IDLoc, "immediate operand value out of range");
1698 case Mips::ADDIUR2_MM:
1699 Opnd = Inst.getOperand(2);
1701 return Error(IDLoc, "expected immediate operand kind");
1702 Imm = Opnd.getImm();
1703 if (!(Imm == 1 || Imm == -1 ||
1704 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1705 return Error(IDLoc, "immediate operand value out of range");
1707 case Mips::ADDIUR1SP_MM:
1708 Opnd = Inst.getOperand(1);
1710 return Error(IDLoc, "expected immediate operand kind");
1711 Imm = Opnd.getImm();
1712 if (OffsetToAlignment(Imm, 4LL))
1713 return Error(IDLoc, "misaligned immediate operand value");
1714 if (Imm < 0 || Imm > 255)
1715 return Error(IDLoc, "immediate operand value out of range");
1717 case Mips::ANDI16_MM:
1718 Opnd = Inst.getOperand(2);
1720 return Error(IDLoc, "expected immediate operand kind");
1721 Imm = Opnd.getImm();
1722 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1723 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1724 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1725 return Error(IDLoc, "immediate operand value out of range");
1727 case Mips::LBU16_MM:
1728 Opnd = Inst.getOperand(2);
1730 return Error(IDLoc, "expected immediate operand kind");
1731 Imm = Opnd.getImm();
1732 if (Imm < -1 || Imm > 14)
1733 return Error(IDLoc, "immediate operand value out of range");
1736 Opnd = Inst.getOperand(2);
1738 return Error(IDLoc, "expected immediate operand kind");
1739 Imm = Opnd.getImm();
1740 if (Imm < 0 || Imm > 15)
1741 return Error(IDLoc, "immediate operand value out of range");
1743 case Mips::LHU16_MM:
1745 Opnd = Inst.getOperand(2);
1747 return Error(IDLoc, "expected immediate operand kind");
1748 Imm = Opnd.getImm();
1749 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1750 return Error(IDLoc, "immediate operand value out of range");
1754 Opnd = Inst.getOperand(2);
1756 return Error(IDLoc, "expected immediate operand kind");
1757 Imm = Opnd.getImm();
1758 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1759 return Error(IDLoc, "immediate operand value out of range");
1763 Opnd = Inst.getOperand(2);
1765 return Error(IDLoc, "expected immediate operand kind");
1766 Imm = Opnd.getImm();
1767 if (!isUInt<5>(Imm))
1768 return Error(IDLoc, "immediate operand value out of range");
1770 case Mips::ADDIUPC_MM:
1771 MCOperand Opnd = Inst.getOperand(1);
1773 return Error(IDLoc, "expected immediate operand kind");
1774 int Imm = Opnd.getImm();
1775 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1776 return Error(IDLoc, "immediate operand value out of range");
1781 if (needsExpansion(Inst)) {
1782 if (expandInstruction(Inst, IDLoc, Instructions))
1785 Instructions.push_back(Inst);
1787 // If this instruction has a delay slot and .set reorder is active,
1788 // emit a NOP after it.
1789 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1790 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1795 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1797 switch (Inst.getOpcode()) {
1798 case Mips::LoadImm32:
1799 case Mips::LoadImm64:
1800 case Mips::LoadAddrImm32:
1801 case Mips::LoadAddrImm64:
1802 case Mips::LoadAddrReg32:
1803 case Mips::LoadAddrReg64:
1804 case Mips::B_MM_Pseudo:
1805 case Mips::B_MMR6_Pseudo:
1808 case Mips::JalOneReg:
1809 case Mips::JalTwoReg:
1828 case Mips::SDivMacro:
1829 case Mips::UDivMacro:
1830 case Mips::DSDivMacro:
1831 case Mips::DUDivMacro:
1840 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1841 SmallVectorImpl<MCInst> &Instructions) {
1842 switch (Inst.getOpcode()) {
1843 default: llvm_unreachable("unimplemented expansion");
1844 case Mips::LoadImm32:
1845 return expandLoadImm(Inst, true, IDLoc, Instructions);
1846 case Mips::LoadImm64:
1847 return expandLoadImm(Inst, false, IDLoc, Instructions);
1848 case Mips::LoadAddrImm32:
1849 case Mips::LoadAddrImm64:
1850 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1851 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1852 "expected immediate operand kind");
1854 return expandLoadAddress(
1855 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1856 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1857 case Mips::LoadAddrReg32:
1858 case Mips::LoadAddrReg64:
1859 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1860 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1861 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1862 "expected immediate operand kind");
1864 return expandLoadAddress(
1865 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1866 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1867 case Mips::B_MM_Pseudo:
1868 case Mips::B_MMR6_Pseudo:
1869 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1872 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1873 case Mips::JalOneReg:
1874 case Mips::JalTwoReg:
1875 return expandJalWithRegs(Inst, IDLoc, Instructions);
1878 return expandBranchImm(Inst, IDLoc, Instructions);
1895 return expandCondBranches(Inst, IDLoc, Instructions);
1896 case Mips::SDivMacro:
1897 return expandDiv(Inst, IDLoc, Instructions, false, true);
1898 case Mips::DSDivMacro:
1899 return expandDiv(Inst, IDLoc, Instructions, true, true);
1900 case Mips::UDivMacro:
1901 return expandDiv(Inst, IDLoc, Instructions, false, false);
1902 case Mips::DUDivMacro:
1903 return expandDiv(Inst, IDLoc, Instructions, true, false);
1905 return expandUlhu(Inst, IDLoc, Instructions);
1907 return expandUlw(Inst, IDLoc, Instructions);
1912 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1913 SmallVectorImpl<MCInst> &Instructions) {
1915 tmpInst.setOpcode(Opcode);
1916 tmpInst.addOperand(MCOperand::createReg(Reg0));
1917 tmpInst.addOperand(Op1);
1918 tmpInst.setLoc(IDLoc);
1919 Instructions.push_back(tmpInst);
1922 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1923 SmallVectorImpl<MCInst> &Instructions) {
1924 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1927 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1928 SmallVectorImpl<MCInst> &Instructions) {
1929 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1932 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1933 SmallVectorImpl<MCInst> &Instructions) {
1935 tmpInst.setOpcode(Opcode);
1936 tmpInst.addOperand(MCOperand::createImm(Imm1));
1937 tmpInst.addOperand(MCOperand::createImm(Imm2));
1938 tmpInst.setLoc(IDLoc);
1939 Instructions.push_back(tmpInst);
1942 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1943 SmallVectorImpl<MCInst> &Instructions) {
1945 tmpInst.setOpcode(Opcode);
1946 tmpInst.addOperand(MCOperand::createReg(Reg0));
1947 tmpInst.setLoc(IDLoc);
1948 Instructions.push_back(tmpInst);
1951 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1952 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1954 tmpInst.setOpcode(Opcode);
1955 tmpInst.addOperand(MCOperand::createReg(Reg0));
1956 tmpInst.addOperand(MCOperand::createReg(Reg1));
1957 tmpInst.addOperand(Op2);
1958 tmpInst.setLoc(IDLoc);
1959 Instructions.push_back(tmpInst);
1962 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1963 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1964 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1968 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1969 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1970 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1974 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1975 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1976 if (ShiftAmount >= 32) {
1977 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1982 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1984 } // end anonymous namespace.
1986 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1987 SmallVectorImpl<MCInst> &Instructions) {
1988 // Create a JALR instruction which is going to replace the pseudo-JAL.
1990 JalrInst.setLoc(IDLoc);
1991 const MCOperand FirstRegOp = Inst.getOperand(0);
1992 const unsigned Opcode = Inst.getOpcode();
1994 if (Opcode == Mips::JalOneReg) {
1995 // jal $rs => jalr $rs
1996 if (inMicroMipsMode()) {
1997 JalrInst.setOpcode(Mips::JALR16_MM);
1998 JalrInst.addOperand(FirstRegOp);
2000 JalrInst.setOpcode(Mips::JALR);
2001 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2002 JalrInst.addOperand(FirstRegOp);
2004 } else if (Opcode == Mips::JalTwoReg) {
2005 // jal $rd, $rs => jalr $rd, $rs
2006 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2007 JalrInst.addOperand(FirstRegOp);
2008 const MCOperand SecondRegOp = Inst.getOperand(1);
2009 JalrInst.addOperand(SecondRegOp);
2011 Instructions.push_back(JalrInst);
2013 // If .set reorder is active, emit a NOP after it.
2014 if (AssemblerOptions.back()->isReorder()) {
2015 // This is a 32-bit NOP because these 2 pseudo-instructions
2016 // do not have a short delay slot.
2018 NopInst.setOpcode(Mips::SLL);
2019 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2020 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2021 NopInst.addOperand(MCOperand::createImm(0));
2022 Instructions.push_back(NopInst);
2028 /// Can the value be represented by a unsigned N-bit value and a shift left?
2029 template<unsigned N>
2030 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2031 unsigned BitNum = findFirstSet(x);
2033 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2036 /// Load (or add) an immediate into a register.
2038 /// @param ImmValue The immediate to load.
2039 /// @param DstReg The register that will hold the immediate.
2040 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2041 /// for a simple initialization.
2042 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2043 /// @param IsAddress True if the immediate represents an address. False if it
2045 /// @param IDLoc Location of the immediate in the source file.
2046 /// @param Instructions The instructions emitted by this expansion.
2047 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2048 unsigned SrcReg, bool Is32BitImm,
2049 bool IsAddress, SMLoc IDLoc,
2050 SmallVectorImpl<MCInst> &Instructions) {
2051 if (!Is32BitImm && !isGP64bit()) {
2052 Error(IDLoc, "instruction requires a 64-bit architecture");
2057 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2058 // Sign extend up to 64-bit so that the predicates match the hardware
2059 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2061 ImmValue = SignExtend64<32>(ImmValue);
2063 Error(IDLoc, "instruction requires a 32-bit immediate");
2068 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2069 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2071 bool UseSrcReg = false;
2072 if (SrcReg != Mips::NoRegister)
2075 unsigned TmpReg = DstReg;
2076 if (UseSrcReg && (DstReg == SrcReg)) {
2077 // At this point we need AT to perform the expansions and we exit if it is
2079 unsigned ATReg = getATReg(IDLoc);
2085 if (isInt<16>(ImmValue)) {
2089 // This doesn't quite follow the usual ABI expectations for N32 but matches
2090 // traditional assembler behaviour. N32 would normally use addiu for both
2091 // integers and addresses.
2092 if (IsAddress && !Is32BitImm) {
2093 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2097 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2101 if (isUInt<16>(ImmValue)) {
2102 unsigned TmpReg = DstReg;
2103 if (SrcReg == DstReg) {
2104 TmpReg = getATReg(IDLoc);
2109 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2111 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2115 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2116 warnIfNoMacro(IDLoc);
2118 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2119 uint16_t Bits15To0 = ImmValue & 0xffff;
2121 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2122 // Traditional behaviour seems to special case this particular value. It's
2123 // not clear why other masks are handled differently.
2124 if (ImmValue == 0xffffffff) {
2125 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2126 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2128 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2132 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2134 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2135 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2137 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2139 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2143 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2145 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2147 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2151 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2153 Error(IDLoc, "instruction requires a 32-bit immediate");
2157 // Traditionally, these immediates are shifted as little as possible and as
2158 // such we align the most significant bit to bit 15 of our temporary.
2159 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2160 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2161 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2162 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2163 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2164 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2167 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2172 warnIfNoMacro(IDLoc);
2174 // The remaining case is packed with a sequence of dsll and ori with zeros
2175 // being omitted and any neighbouring dsll's being coalesced.
2176 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2178 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2179 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2180 IDLoc, Instructions))
2183 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2184 // skip it and defer the shift to the next chunk.
2185 unsigned ShiftCarriedForwards = 16;
2186 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2187 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2189 if (ImmChunk != 0) {
2190 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2192 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2193 ShiftCarriedForwards = 0;
2196 ShiftCarriedForwards += 16;
2198 ShiftCarriedForwards -= 16;
2200 // Finish any remaining shifts left by trailing zeros.
2201 if (ShiftCarriedForwards)
2202 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2206 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2211 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2212 SmallVectorImpl<MCInst> &Instructions) {
2213 const MCOperand &ImmOp = Inst.getOperand(1);
2214 assert(ImmOp.isImm() && "expected immediate operand kind");
2215 const MCOperand &DstRegOp = Inst.getOperand(0);
2216 assert(DstRegOp.isReg() && "expected register operand kind");
2218 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2219 Is32BitImm, false, IDLoc, Instructions))
2225 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2226 const MCOperand &Offset,
2227 bool Is32BitAddress, SMLoc IDLoc,
2228 SmallVectorImpl<MCInst> &Instructions) {
2229 // la can't produce a usable address when addresses are 64-bit.
2230 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2231 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2232 // We currently can't do this because we depend on the equality
2233 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2234 Error(IDLoc, "la used to load 64-bit address");
2235 // Continue as if we had 'dla' instead.
2236 Is32BitAddress = false;
2239 // dla requires 64-bit addresses.
2240 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2241 Error(IDLoc, "instruction requires a 64-bit architecture");
2245 if (!Offset.isImm())
2246 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2247 Is32BitAddress, IDLoc, Instructions);
2249 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2250 IDLoc, Instructions);
2253 bool MipsAsmParser::loadAndAddSymbolAddress(
2254 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2255 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2256 warnIfNoMacro(IDLoc);
2258 // FIXME: The way we're handling symbols right now prevents simple expressions
2259 // like foo+8. We'll be able to fix this once our unary operators (%hi
2260 // and similar) are treated as operators rather than as fixup types.
2261 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2262 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2263 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2264 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2265 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2267 bool UseSrcReg = SrcReg != Mips::NoRegister;
2269 // This is the 64-bit symbol address expansion.
2270 if (ABI.ArePtrs64bit() && isGP64bit()) {
2271 // We always need AT for the 64-bit expansion.
2272 // If it is not available we exit.
2273 unsigned ATReg = getATReg(IDLoc);
2277 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2278 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2279 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2280 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2282 if (UseSrcReg && (DstReg == SrcReg)) {
2283 // If $rs is the same as $rd:
2284 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2285 // daddiu $at, $at, %higher(sym)
2286 // dsll $at, $at, 16
2287 // daddiu $at, $at, %hi(sym)
2288 // dsll $at, $at, 16
2289 // daddiu $at, $at, %lo(sym)
2290 // daddu $rd, $at, $rd
2291 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2293 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2294 IDLoc, Instructions);
2295 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2296 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2298 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2299 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2301 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2306 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2307 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2308 // lui $at, %hi(sym)
2309 // daddiu $rd, $rd, %higher(sym)
2310 // daddiu $at, $at, %lo(sym)
2311 // dsll32 $rd, $rd, 0
2312 // daddu $rd, $rd, $at
2313 // (daddu $rd, $rd, $rs)
2314 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2316 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2318 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2319 IDLoc, Instructions);
2320 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2322 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2323 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2325 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2330 // And now, the 32-bit symbol address expansion:
2331 // If $rs is the same as $rd:
2332 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2333 // ori $at, $at, %lo(sym)
2334 // addu $rd, $at, $rd
2335 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2336 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2337 // ori $rd, $rd, %lo(sym)
2338 // (addu $rd, $rd, $rs)
2339 unsigned TmpReg = DstReg;
2340 if (UseSrcReg && (DstReg == SrcReg)) {
2341 // If $rs is the same as $rd, we need to use AT.
2342 // If it is not available we exit.
2343 unsigned ATReg = getATReg(IDLoc);
2349 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2350 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2354 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2356 assert(DstReg == TmpReg);
2361 bool MipsAsmParser::expandUncondBranchMMPseudo(
2362 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2363 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2364 "unexpected number of operands");
2366 MCOperand Offset = Inst.getOperand(0);
2367 if (Offset.isExpr()) {
2369 Inst.setOpcode(Mips::BEQ_MM);
2370 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2371 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2372 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2374 assert(Offset.isImm() && "expected immediate operand kind");
2375 if (isIntN(11, Offset.getImm())) {
2376 // If offset fits into 11 bits then this instruction becomes microMIPS
2377 // 16-bit unconditional branch instruction.
2378 if (inMicroMipsMode())
2379 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2381 if (!isIntN(17, Offset.getImm()))
2382 Error(IDLoc, "branch target out of range");
2383 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2384 Error(IDLoc, "branch to misaligned address");
2386 Inst.setOpcode(Mips::BEQ_MM);
2387 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2388 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2389 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2392 Instructions.push_back(Inst);
2394 // If .set reorder is active and branch instruction has a delay slot,
2395 // emit a NOP after it.
2396 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2397 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2398 createNop(true, IDLoc, Instructions);
2403 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2404 SmallVectorImpl<MCInst> &Instructions) {
2405 const MCOperand &DstRegOp = Inst.getOperand(0);
2406 assert(DstRegOp.isReg() && "expected register operand kind");
2408 const MCOperand &ImmOp = Inst.getOperand(1);
2409 assert(ImmOp.isImm() && "expected immediate operand kind");
2411 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2412 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2414 unsigned OpCode = 0;
2415 switch(Inst.getOpcode()) {
2423 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2427 int64_t ImmValue = ImmOp.getImm();
2428 if (ImmValue == 0) {
2430 BranchInst.setOpcode(OpCode);
2431 BranchInst.addOperand(DstRegOp);
2432 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2433 BranchInst.addOperand(MemOffsetOp);
2434 Instructions.push_back(BranchInst);
2436 warnIfNoMacro(IDLoc);
2438 unsigned ATReg = getATReg(IDLoc);
2442 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2443 IDLoc, Instructions))
2447 BranchInst.setOpcode(OpCode);
2448 BranchInst.addOperand(DstRegOp);
2449 BranchInst.addOperand(MCOperand::createReg(ATReg));
2450 BranchInst.addOperand(MemOffsetOp);
2451 Instructions.push_back(BranchInst);
2456 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2457 SmallVectorImpl<MCInst> &Instructions,
2458 bool isLoad, bool isImmOpnd) {
2460 unsigned ImmOffset, HiOffset, LoOffset;
2461 const MCExpr *ExprOffset;
2463 // 1st operand is either the source or destination register.
2464 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2465 unsigned RegOpNum = Inst.getOperand(0).getReg();
2466 // 2nd operand is the base register.
2467 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2468 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2469 // 3rd operand is either an immediate or expression.
2471 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2472 ImmOffset = Inst.getOperand(2).getImm();
2473 LoOffset = ImmOffset & 0x0000ffff;
2474 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2475 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2476 if (LoOffset & 0x8000)
2479 ExprOffset = Inst.getOperand(2).getExpr();
2480 // All instructions will have the same location.
2481 TempInst.setLoc(IDLoc);
2482 // These are some of the types of expansions we perform here:
2483 // 1) lw $8, sym => lui $8, %hi(sym)
2484 // lw $8, %lo(sym)($8)
2485 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2487 // lw $8, %lo(offset)($9)
2488 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2490 // lw $8, %lo(offset)($at)
2491 // 4) sw $8, sym => lui $at, %hi(sym)
2492 // sw $8, %lo(sym)($at)
2493 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2495 // sw $8, %lo(offset)($at)
2496 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2497 // ldc1 $f0, %lo(sym)($at)
2499 // For load instructions we can use the destination register as a temporary
2500 // if base and dst are different (examples 1 and 2) and if the base register
2501 // is general purpose otherwise we must use $at (example 6) and error if it's
2502 // not available. For stores we must use $at (examples 4 and 5) because we
2503 // must not clobber the source register setting up the offset.
2504 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2505 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2506 unsigned RegClassIDOp0 =
2507 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2508 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2509 (RegClassIDOp0 == Mips::GPR64RegClassID);
2510 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2511 TmpRegNum = RegOpNum;
2513 // At this point we need AT to perform the expansions and we exit if it is
2515 TmpRegNum = getATReg(IDLoc);
2520 TempInst.setOpcode(Mips::LUi);
2521 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2523 TempInst.addOperand(MCOperand::createImm(HiOffset));
2525 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2526 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2528 // Add the instruction to the list.
2529 Instructions.push_back(TempInst);
2530 // Prepare TempInst for next instruction.
2532 // Add temp register to base.
2533 if (BaseRegNum != Mips::ZERO) {
2534 TempInst.setOpcode(Mips::ADDu);
2535 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2536 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2537 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2538 Instructions.push_back(TempInst);
2541 // And finally, create original instruction with low part
2542 // of offset and new base.
2543 TempInst.setOpcode(Inst.getOpcode());
2544 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2545 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2547 TempInst.addOperand(MCOperand::createImm(LoOffset));
2549 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2550 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2552 Instructions.push_back(TempInst);
2557 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2558 SmallVectorImpl<MCInst> &Instructions) {
2559 unsigned OpNum = Inst.getNumOperands();
2560 unsigned Opcode = Inst.getOpcode();
2561 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2563 assert (Inst.getOperand(OpNum - 1).isImm() &&
2564 Inst.getOperand(OpNum - 2).isReg() &&
2565 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2567 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2568 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2569 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2570 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2571 // It can be implemented as SWM16 or LWM16 instruction.
2572 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2574 Inst.setOpcode(NewOpcode);
2575 Instructions.push_back(Inst);
2579 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2580 SmallVectorImpl<MCInst> &Instructions) {
2581 unsigned PseudoOpcode = Inst.getOpcode();
2582 unsigned SrcReg = Inst.getOperand(0).getReg();
2583 unsigned TrgReg = Inst.getOperand(1).getReg();
2584 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2586 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2587 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2589 switch (PseudoOpcode) {
2594 AcceptsEquality = false;
2595 ReverseOrderSLT = false;
2596 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2597 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2598 ZeroSrcOpcode = Mips::BGTZ;
2599 ZeroTrgOpcode = Mips::BLTZ;
2605 AcceptsEquality = true;
2606 ReverseOrderSLT = true;
2607 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2608 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2609 ZeroSrcOpcode = Mips::BGEZ;
2610 ZeroTrgOpcode = Mips::BLEZ;
2616 AcceptsEquality = true;
2617 ReverseOrderSLT = false;
2618 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2619 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2620 ZeroSrcOpcode = Mips::BLEZ;
2621 ZeroTrgOpcode = Mips::BGEZ;
2627 AcceptsEquality = false;
2628 ReverseOrderSLT = true;
2629 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2630 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2631 ZeroSrcOpcode = Mips::BLTZ;
2632 ZeroTrgOpcode = Mips::BGTZ;
2635 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2639 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2640 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2641 if (IsSrcRegZero && IsTrgRegZero) {
2642 // FIXME: All of these Opcode-specific if's are needed for compatibility
2643 // with GAS' behaviour. However, they may not generate the most efficient
2644 // code in some circumstances.
2645 if (PseudoOpcode == Mips::BLT) {
2646 BranchInst.setOpcode(Mips::BLTZ);
2647 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2648 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2649 Instructions.push_back(BranchInst);
2652 if (PseudoOpcode == Mips::BLE) {
2653 BranchInst.setOpcode(Mips::BLEZ);
2654 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2655 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2656 Instructions.push_back(BranchInst);
2657 Warning(IDLoc, "branch is always taken");
2660 if (PseudoOpcode == Mips::BGE) {
2661 BranchInst.setOpcode(Mips::BGEZ);
2662 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2663 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2664 Instructions.push_back(BranchInst);
2665 Warning(IDLoc, "branch is always taken");
2668 if (PseudoOpcode == Mips::BGT) {
2669 BranchInst.setOpcode(Mips::BGTZ);
2670 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2671 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2672 Instructions.push_back(BranchInst);
2675 if (PseudoOpcode == Mips::BGTU) {
2676 BranchInst.setOpcode(Mips::BNE);
2677 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2678 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2679 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2680 Instructions.push_back(BranchInst);
2683 if (AcceptsEquality) {
2684 // If both registers are $0 and the pseudo-branch accepts equality, it
2685 // will always be taken, so we emit an unconditional branch.
2686 BranchInst.setOpcode(Mips::BEQ);
2687 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2688 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2689 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2690 Instructions.push_back(BranchInst);
2691 Warning(IDLoc, "branch is always taken");
2694 // If both registers are $0 and the pseudo-branch does not accept
2695 // equality, it will never be taken, so we don't have to emit anything.
2698 if (IsSrcRegZero || IsTrgRegZero) {
2699 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2700 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2701 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2702 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2703 // the pseudo-branch will never be taken, so we don't emit anything.
2704 // This only applies to unsigned pseudo-branches.
2707 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2708 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2709 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2710 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2711 // the pseudo-branch will always be taken, so we emit an unconditional
2713 // This only applies to unsigned pseudo-branches.
2714 BranchInst.setOpcode(Mips::BEQ);
2715 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2716 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2717 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2718 Instructions.push_back(BranchInst);
2719 Warning(IDLoc, "branch is always taken");
2723 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2724 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2725 // the pseudo-branch will be taken only when the non-zero register is
2726 // different from 0, so we emit a BNEZ.
2728 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2729 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2730 // the pseudo-branch will be taken only when the non-zero register is
2731 // equal to 0, so we emit a BEQZ.
2733 // Because only BLEU and BGEU branch on equality, we can use the
2734 // AcceptsEquality variable to decide when to emit the BEQZ.
2735 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2736 BranchInst.addOperand(
2737 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2738 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2739 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2740 Instructions.push_back(BranchInst);
2743 // If we have a signed pseudo-branch and one of the registers is $0,
2744 // we can use an appropriate compare-to-zero branch. We select which one
2745 // to use in the switch statement above.
2746 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2747 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2748 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2749 Instructions.push_back(BranchInst);
2753 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2754 // expansions. If it is not available, we return.
2755 unsigned ATRegNum = getATReg(IDLoc);
2759 warnIfNoMacro(IDLoc);
2761 // SLT fits well with 2 of our 4 pseudo-branches:
2762 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2763 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2764 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2765 // This is accomplished by using a BNEZ with the result of the SLT.
2767 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2768 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2769 // Because only BGE and BLE branch on equality, we can use the
2770 // AcceptsEquality variable to decide when to emit the BEQZ.
2771 // Note that the order of the SLT arguments doesn't change between
2774 // The same applies to the unsigned variants, except that SLTu is used
2777 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2778 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2779 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2780 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2781 Instructions.push_back(SetInst);
2784 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2786 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQL : Mips::BNEL);
2787 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2788 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2789 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2790 Instructions.push_back(BranchInst);
2794 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2795 SmallVectorImpl<MCInst> &Instructions,
2796 const bool IsMips64, const bool Signed) {
2797 if (hasMips32r6()) {
2798 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2802 warnIfNoMacro(IDLoc);
2804 const MCOperand &RsRegOp = Inst.getOperand(0);
2805 assert(RsRegOp.isReg() && "expected register operand kind");
2806 unsigned RsReg = RsRegOp.getReg();
2808 const MCOperand &RtRegOp = Inst.getOperand(1);
2809 assert(RtRegOp.isReg() && "expected register operand kind");
2810 unsigned RtReg = RtRegOp.getReg();
2815 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2816 ZeroReg = Mips::ZERO_64;
2818 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2819 ZeroReg = Mips::ZERO;
2822 bool UseTraps = useTraps();
2824 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2825 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2826 Warning(IDLoc, "dividing zero by zero");
2828 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2830 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2834 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2838 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2843 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2844 Warning(IDLoc, "division by zero");
2847 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2851 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2856 // FIXME: The values for these two BranchTarget variables may be different in
2857 // micromips. These magic numbers need to be removed.
2858 unsigned BranchTargetNoTraps;
2859 unsigned BranchTarget;
2862 BranchTarget = IsMips64 ? 12 : 8;
2863 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2865 BranchTarget = IsMips64 ? 20 : 16;
2866 BranchTargetNoTraps = 8;
2867 // Branch to the li instruction.
2868 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2872 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2875 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2878 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2882 unsigned ATReg = getATReg(IDLoc);
2886 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2888 // Branch to the mflo instruction.
2889 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2890 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2891 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2893 // Branch to the mflo instruction.
2894 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2895 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2899 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2901 // Branch to the mflo instruction.
2902 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2903 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2904 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2906 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2910 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2911 SmallVectorImpl<MCInst> &Instructions) {
2912 if (hasMips32r6() || hasMips64r6()) {
2913 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2917 warnIfNoMacro(IDLoc);
2919 const MCOperand &DstRegOp = Inst.getOperand(0);
2920 assert(DstRegOp.isReg() && "expected register operand kind");
2922 const MCOperand &SrcRegOp = Inst.getOperand(1);
2923 assert(SrcRegOp.isReg() && "expected register operand kind");
2925 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2926 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2928 unsigned DstReg = DstRegOp.getReg();
2929 unsigned SrcReg = SrcRegOp.getReg();
2930 int64_t OffsetValue = OffsetImmOp.getImm();
2932 // NOTE: We always need AT for ULHU, as it is always used as the source
2933 // register for one of the LBu's.
2934 unsigned ATReg = getATReg(IDLoc);
2938 // When the value of offset+1 does not fit in 16 bits, we have to load the
2939 // offset in AT, (D)ADDu the original source register (if there was one), and
2940 // then use AT as the source register for the 2 generated LBu's.
2941 bool LoadedOffsetInAT = false;
2942 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2943 LoadedOffsetInAT = true;
2945 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2946 true, IDLoc, Instructions))
2949 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2950 // because it will make our output more similar to GAS'. For example,
2951 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2952 // instead of just an "ori $1, $9, 32768".
2953 // NOTE: If there is no source register specified in the ULHU, the parser
2954 // will interpret it as $0.
2955 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2956 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2959 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2960 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2961 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2963 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2965 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2966 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2968 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2969 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2972 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2975 TmpInst.setOpcode(Mips::LBu);
2976 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2977 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2978 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2979 Instructions.push_back(TmpInst);
2982 TmpInst.setOpcode(Mips::LBu);
2983 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2984 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2985 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2986 Instructions.push_back(TmpInst);
2989 TmpInst.setOpcode(Mips::SLL);
2990 TmpInst.addOperand(MCOperand::createReg(SllReg));
2991 TmpInst.addOperand(MCOperand::createReg(SllReg));
2992 TmpInst.addOperand(MCOperand::createImm(8));
2993 Instructions.push_back(TmpInst);
2996 TmpInst.setOpcode(Mips::OR);
2997 TmpInst.addOperand(MCOperand::createReg(DstReg));
2998 TmpInst.addOperand(MCOperand::createReg(DstReg));
2999 TmpInst.addOperand(MCOperand::createReg(ATReg));
3000 Instructions.push_back(TmpInst);
3005 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3006 SmallVectorImpl<MCInst> &Instructions) {
3007 if (hasMips32r6() || hasMips64r6()) {
3008 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3012 const MCOperand &DstRegOp = Inst.getOperand(0);
3013 assert(DstRegOp.isReg() && "expected register operand kind");
3015 const MCOperand &SrcRegOp = Inst.getOperand(1);
3016 assert(SrcRegOp.isReg() && "expected register operand kind");
3018 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3019 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3021 unsigned SrcReg = SrcRegOp.getReg();
3022 int64_t OffsetValue = OffsetImmOp.getImm();
3025 // When the value of offset+3 does not fit in 16 bits, we have to load the
3026 // offset in AT, (D)ADDu the original source register (if there was one), and
3027 // then use AT as the source register for the generated LWL and LWR.
3028 bool LoadedOffsetInAT = false;
3029 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3030 ATReg = getATReg(IDLoc);
3033 LoadedOffsetInAT = true;
3035 warnIfNoMacro(IDLoc);
3037 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3038 true, IDLoc, Instructions))
3041 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3042 // because it will make our output more similar to GAS'. For example,
3043 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3044 // instead of just an "ori $1, $9, 32768".
3045 // NOTE: If there is no source register specified in the ULW, the parser
3046 // will interpret it as $0.
3047 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3048 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3051 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3052 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3054 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3055 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3057 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3058 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3061 MCInst LeftLoadInst;
3062 LeftLoadInst.setOpcode(Mips::LWL);
3063 LeftLoadInst.addOperand(DstRegOp);
3064 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3065 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3066 Instructions.push_back(LeftLoadInst);
3068 MCInst RightLoadInst;
3069 RightLoadInst.setOpcode(Mips::LWR);
3070 RightLoadInst.addOperand(DstRegOp);
3071 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3072 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3073 Instructions.push_back(RightLoadInst);
3078 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3079 SmallVectorImpl<MCInst> &Instructions) {
3081 if (hasShortDelaySlot) {
3082 NopInst.setOpcode(Mips::MOVE16_MM);
3083 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3084 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3086 NopInst.setOpcode(Mips::SLL);
3087 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3088 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3089 NopInst.addOperand(MCOperand::createImm(0));
3091 Instructions.push_back(NopInst);
3094 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3095 unsigned TrgReg, bool Is64Bit,
3096 SmallVectorImpl<MCInst> &Instructions) {
3097 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3101 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3102 // As described by the Mips32r2 spec, the registers Rd and Rs for
3103 // jalr.hb must be different.
3104 unsigned Opcode = Inst.getOpcode();
3106 if (Opcode == Mips::JALR_HB &&
3107 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3108 return Match_RequiresDifferentSrcAndDst;
3110 return Match_Success;
3113 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3114 OperandVector &Operands,
3116 uint64_t &ErrorInfo,
3117 bool MatchingInlineAsm) {
3120 SmallVector<MCInst, 8> Instructions;
3121 unsigned MatchResult =
3122 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3124 switch (MatchResult) {
3125 case Match_Success: {
3126 if (processInstruction(Inst, IDLoc, Instructions))
3128 for (unsigned i = 0; i < Instructions.size(); i++)
3129 Out.EmitInstruction(Instructions[i], STI);
3132 case Match_MissingFeature:
3133 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3135 case Match_InvalidOperand: {
3136 SMLoc ErrorLoc = IDLoc;
3137 if (ErrorInfo != ~0ULL) {
3138 if (ErrorInfo >= Operands.size())
3139 return Error(IDLoc, "too few operands for instruction");
3141 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3142 if (ErrorLoc == SMLoc())
3146 return Error(ErrorLoc, "invalid operand for instruction");
3148 case Match_MnemonicFail:
3149 return Error(IDLoc, "invalid instruction");
3150 case Match_RequiresDifferentSrcAndDst:
3151 return Error(IDLoc, "source and destination must be different");
3154 llvm_unreachable("Implement any new match types added!");
3157 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3158 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3159 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3160 ") without \".set noat\"");
3163 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3164 if (!AssemblerOptions.back()->isMacro())
3165 Warning(Loc, "macro instruction expanded into multiple instructions");
3169 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3170 SMRange Range, bool ShowColors) {
3171 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3172 Range, SMFixIt(Range, FixMsg),
3176 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3179 CC = StringSwitch<unsigned>(Name)
3215 if (!(isABI_N32() || isABI_N64()))
3218 if (12 <= CC && CC <= 15) {
3219 // Name is one of t4-t7
3220 AsmToken RegTok = getLexer().peekTok();
3221 SMRange RegRange = RegTok.getLocRange();
3223 StringRef FixedName = StringSwitch<StringRef>(Name)
3229 assert(FixedName != "" && "Register name is not one of t4-t7.");
3231 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3232 "Did you mean $" + FixedName + "?", RegRange);
3235 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3236 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3237 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3238 if (8 <= CC && CC <= 11)
3242 CC = StringSwitch<unsigned>(Name)
3254 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3257 CC = StringSwitch<unsigned>(Name)
3258 .Case("hwr_cpunum", 0)
3259 .Case("hwr_synci_step", 1)
3261 .Case("hwr_ccres", 3)
3262 .Case("hwr_ulr", 29)
3268 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3270 if (Name[0] == 'f') {
3271 StringRef NumString = Name.substr(1);
3273 if (NumString.getAsInteger(10, IntVal))
3274 return -1; // This is not an integer.
3275 if (IntVal > 31) // Maximum index for fpu register.
3282 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3284 if (Name.startswith("fcc")) {
3285 StringRef NumString = Name.substr(3);
3287 if (NumString.getAsInteger(10, IntVal))
3288 return -1; // This is not an integer.
3289 if (IntVal > 7) // There are only 8 fcc registers.
3296 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3298 if (Name.startswith("ac")) {
3299 StringRef NumString = Name.substr(2);
3301 if (NumString.getAsInteger(10, IntVal))
3302 return -1; // This is not an integer.
3303 if (IntVal > 3) // There are only 3 acc registers.
3310 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3313 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3322 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3325 CC = StringSwitch<unsigned>(Name)
3328 .Case("msaaccess", 2)
3330 .Case("msamodify", 4)
3331 .Case("msarequest", 5)
3333 .Case("msaunmap", 7)
3339 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3340 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3342 reportParseError(Loc,
3343 "pseudo-instruction requires $at, which is not available");
3346 unsigned AT = getReg(
3347 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3351 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3352 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3355 unsigned MipsAsmParser::getGPR(int RegNo) {
3356 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3360 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3362 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3365 return getReg(RegClass, RegNum);
3368 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3369 MCAsmParser &Parser = getParser();
3370 DEBUG(dbgs() << "parseOperand\n");
3372 // Check if the current operand has a custom associated parser, if so, try to
3373 // custom parse the operand, or fallback to the general approach.
3374 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3375 if (ResTy == MatchOperand_Success)
3377 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3378 // there was a match, but an error occurred, in which case, just return that
3379 // the operand parsing failed.
3380 if (ResTy == MatchOperand_ParseFail)
3383 DEBUG(dbgs() << ".. Generic Parser\n");
3385 switch (getLexer().getKind()) {
3387 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3389 case AsmToken::Dollar: {
3390 // Parse the register.
3391 SMLoc S = Parser.getTok().getLoc();
3393 // Almost all registers have been parsed by custom parsers. There is only
3394 // one exception to this. $zero (and it's alias $0) will reach this point
3395 // for div, divu, and similar instructions because it is not an operand
3396 // to the instruction definition but an explicit register. Special case
3397 // this situation for now.
3398 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3401 // Maybe it is a symbol reference.
3402 StringRef Identifier;
3403 if (Parser.parseIdentifier(Identifier))
3406 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3407 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3408 // Otherwise create a symbol reference.
3410 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3412 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3415 // Else drop to expression parsing.
3416 case AsmToken::LParen:
3417 case AsmToken::Minus:
3418 case AsmToken::Plus:
3419 case AsmToken::Integer:
3420 case AsmToken::Tilde:
3421 case AsmToken::String: {
3422 DEBUG(dbgs() << ".. generic integer\n");
3423 OperandMatchResultTy ResTy = parseImm(Operands);
3424 return ResTy != MatchOperand_Success;
3426 case AsmToken::Percent: {
3427 // It is a symbol reference or constant expression.
3428 const MCExpr *IdVal;
3429 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3430 if (parseRelocOperand(IdVal))
3433 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3435 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3437 } // case AsmToken::Percent
3438 } // switch(getLexer().getKind())
3442 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3443 StringRef RelocStr) {
3445 // Check the type of the expression.
3446 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3447 // It's a constant, evaluate reloc value.
3449 switch (getVariantKind(RelocStr)) {
3450 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3451 // Get the 1st 16-bits.
3452 Val = MCE->getValue() & 0xffff;
3454 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3455 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3456 // 16 bits being negative.
3457 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3459 case MCSymbolRefExpr::VK_Mips_HIGHER:
3460 // Get the 3rd 16-bits.
3461 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3463 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3464 // Get the 4th 16-bits.
3465 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3468 report_fatal_error("unsupported reloc value");
3470 return MCConstantExpr::create(Val, getContext());
3473 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3474 // It's a symbol, create a symbolic expression from the symbol.
3475 const MCSymbol *Symbol = &MSRE->getSymbol();
3476 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3477 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3481 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3482 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3484 // Try to create target expression.
3485 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3486 return MipsMCExpr::create(VK, Expr, getContext());
3488 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3489 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3490 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3494 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3495 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3496 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3499 // Just return the original expression.
3503 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3505 switch (Expr->getKind()) {
3506 case MCExpr::Constant:
3508 case MCExpr::SymbolRef:
3509 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3510 case MCExpr::Binary:
3511 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3512 if (!isEvaluated(BE->getLHS()))
3514 return isEvaluated(BE->getRHS());
3517 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3518 case MCExpr::Target:
3524 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3525 MCAsmParser &Parser = getParser();
3526 Parser.Lex(); // Eat the % token.
3527 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3528 if (Tok.isNot(AsmToken::Identifier))
3531 std::string Str = Tok.getIdentifier();
3533 Parser.Lex(); // Eat the identifier.
3534 // Now make an expression from the rest of the operand.
3535 const MCExpr *IdVal;
3538 if (getLexer().getKind() == AsmToken::LParen) {
3540 Parser.Lex(); // Eat the '(' token.
3541 if (getLexer().getKind() == AsmToken::Percent) {
3542 Parser.Lex(); // Eat the % token.
3543 const AsmToken &nextTok = Parser.getTok();
3544 if (nextTok.isNot(AsmToken::Identifier))
3547 Str += nextTok.getIdentifier();
3548 Parser.Lex(); // Eat the identifier.
3549 if (getLexer().getKind() != AsmToken::LParen)
3554 if (getParser().parseParenExpression(IdVal, EndLoc))
3557 while (getLexer().getKind() == AsmToken::RParen)
3558 Parser.Lex(); // Eat the ')' token.
3561 return true; // Parenthesis must follow the relocation operand.
3563 Res = evaluateRelocExpr(IdVal, Str);
3567 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3569 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3570 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3571 if (ResTy == MatchOperand_Success) {
3572 assert(Operands.size() == 1);
3573 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3574 StartLoc = Operand.getStartLoc();
3575 EndLoc = Operand.getEndLoc();
3577 // AFAIK, we only support numeric registers and named GPR's in CFI
3579 // Don't worry about eating tokens before failing. Using an unrecognised
3580 // register is a parse error.
3581 if (Operand.isGPRAsmReg()) {
3582 // Resolve to GPR32 or GPR64 appropriately.
3583 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3586 return (RegNo == (unsigned)-1);
3589 assert(Operands.size() == 0);
3590 return (RegNo == (unsigned)-1);
3593 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3594 MCAsmParser &Parser = getParser();
3597 unsigned NumOfLParen = 0;
3599 while (getLexer().getKind() == AsmToken::LParen) {
3604 switch (getLexer().getKind()) {
3607 case AsmToken::Identifier:
3608 case AsmToken::LParen:
3609 case AsmToken::Integer:
3610 case AsmToken::Minus:
3611 case AsmToken::Plus:
3613 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3615 Result = (getParser().parseExpression(Res));
3616 while (getLexer().getKind() == AsmToken::RParen)
3619 case AsmToken::Percent:
3620 Result = parseRelocOperand(Res);
3625 MipsAsmParser::OperandMatchResultTy
3626 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3627 MCAsmParser &Parser = getParser();
3628 DEBUG(dbgs() << "parseMemOperand\n");
3629 const MCExpr *IdVal = nullptr;
3631 bool isParenExpr = false;
3632 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3633 // First operand is the offset.
3634 S = Parser.getTok().getLoc();
3636 if (getLexer().getKind() == AsmToken::LParen) {
3641 if (getLexer().getKind() != AsmToken::Dollar) {
3642 if (parseMemOffset(IdVal, isParenExpr))
3643 return MatchOperand_ParseFail;
3645 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3646 if (Tok.isNot(AsmToken::LParen)) {
3647 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3648 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3650 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3651 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3652 return MatchOperand_Success;
3654 if (Tok.is(AsmToken::EndOfStatement)) {
3656 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3658 // Zero register assumed, add a memory operand with ZERO as its base.
3659 // "Base" will be managed by k_Memory.
3660 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3663 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3664 return MatchOperand_Success;
3666 Error(Parser.getTok().getLoc(), "'(' expected");
3667 return MatchOperand_ParseFail;
3670 Parser.Lex(); // Eat the '(' token.
3673 Res = parseAnyRegister(Operands);
3674 if (Res != MatchOperand_Success)
3677 if (Parser.getTok().isNot(AsmToken::RParen)) {
3678 Error(Parser.getTok().getLoc(), "')' expected");
3679 return MatchOperand_ParseFail;
3682 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3684 Parser.Lex(); // Eat the ')' token.
3687 IdVal = MCConstantExpr::create(0, getContext());
3689 // Replace the register operand with the memory operand.
3690 std::unique_ptr<MipsOperand> op(
3691 static_cast<MipsOperand *>(Operands.back().release()));
3692 // Remove the register from the operands.
3693 // "op" will be managed by k_Memory.
3694 Operands.pop_back();
3695 // Add the memory operand.
3696 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3698 if (IdVal->evaluateAsAbsolute(Imm))
3699 IdVal = MCConstantExpr::create(Imm, getContext());
3700 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3701 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3705 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3706 return MatchOperand_Success;
3709 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3710 MCAsmParser &Parser = getParser();
3711 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3713 SMLoc S = Parser.getTok().getLoc();
3715 if (Sym->isVariable())
3716 Expr = Sym->getVariableValue();
3719 if (Expr->getKind() == MCExpr::SymbolRef) {
3720 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3721 StringRef DefSymbol = Ref->getSymbol().getName();
3722 if (DefSymbol.startswith("$")) {
3723 OperandMatchResultTy ResTy =
3724 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3725 if (ResTy == MatchOperand_Success) {
3728 } else if (ResTy == MatchOperand_ParseFail)
3729 llvm_unreachable("Should never ParseFail");
3732 } else if (Expr->getKind() == MCExpr::Constant) {
3734 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3736 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3743 MipsAsmParser::OperandMatchResultTy
3744 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3745 StringRef Identifier,
3747 int Index = matchCPURegisterName(Identifier);
3749 Operands.push_back(MipsOperand::createGPRReg(
3750 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3751 return MatchOperand_Success;
3754 Index = matchHWRegsRegisterName(Identifier);
3756 Operands.push_back(MipsOperand::createHWRegsReg(
3757 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3758 return MatchOperand_Success;
3761 Index = matchFPURegisterName(Identifier);
3763 Operands.push_back(MipsOperand::createFGRReg(
3764 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3765 return MatchOperand_Success;
3768 Index = matchFCCRegisterName(Identifier);
3770 Operands.push_back(MipsOperand::createFCCReg(
3771 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3772 return MatchOperand_Success;
3775 Index = matchACRegisterName(Identifier);
3777 Operands.push_back(MipsOperand::createACCReg(
3778 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3779 return MatchOperand_Success;
3782 Index = matchMSA128RegisterName(Identifier);
3784 Operands.push_back(MipsOperand::createMSA128Reg(
3785 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3786 return MatchOperand_Success;
3789 Index = matchMSA128CtrlRegisterName(Identifier);
3791 Operands.push_back(MipsOperand::createMSACtrlReg(
3792 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3793 return MatchOperand_Success;
3796 return MatchOperand_NoMatch;
3799 MipsAsmParser::OperandMatchResultTy
3800 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3801 MCAsmParser &Parser = getParser();
3802 auto Token = Parser.getLexer().peekTok(false);
3804 if (Token.is(AsmToken::Identifier)) {
3805 DEBUG(dbgs() << ".. identifier\n");
3806 StringRef Identifier = Token.getIdentifier();
3807 OperandMatchResultTy ResTy =
3808 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3810 } else if (Token.is(AsmToken::Integer)) {
3811 DEBUG(dbgs() << ".. integer\n");
3812 Operands.push_back(MipsOperand::createNumericReg(
3813 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3815 return MatchOperand_Success;
3818 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3820 return MatchOperand_NoMatch;
3823 MipsAsmParser::OperandMatchResultTy
3824 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3825 MCAsmParser &Parser = getParser();
3826 DEBUG(dbgs() << "parseAnyRegister\n");
3828 auto Token = Parser.getTok();
3830 SMLoc S = Token.getLoc();
3832 if (Token.isNot(AsmToken::Dollar)) {
3833 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3834 if (Token.is(AsmToken::Identifier)) {
3835 if (searchSymbolAlias(Operands))
3836 return MatchOperand_Success;
3838 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3839 return MatchOperand_NoMatch;
3841 DEBUG(dbgs() << ".. $\n");
3843 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3844 if (ResTy == MatchOperand_Success) {
3846 Parser.Lex(); // identifier
3851 MipsAsmParser::OperandMatchResultTy
3852 MipsAsmParser::parseImm(OperandVector &Operands) {
3853 MCAsmParser &Parser = getParser();
3854 switch (getLexer().getKind()) {
3856 return MatchOperand_NoMatch;
3857 case AsmToken::LParen:
3858 case AsmToken::Minus:
3859 case AsmToken::Plus:
3860 case AsmToken::Integer:
3861 case AsmToken::Tilde:
3862 case AsmToken::String:
3866 const MCExpr *IdVal;
3867 SMLoc S = Parser.getTok().getLoc();
3868 if (getParser().parseExpression(IdVal))
3869 return MatchOperand_ParseFail;
3871 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3872 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3873 return MatchOperand_Success;
3876 MipsAsmParser::OperandMatchResultTy
3877 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3878 MCAsmParser &Parser = getParser();
3879 DEBUG(dbgs() << "parseJumpTarget\n");
3881 SMLoc S = getLexer().getLoc();
3883 // Integers and expressions are acceptable
3884 OperandMatchResultTy ResTy = parseImm(Operands);
3885 if (ResTy != MatchOperand_NoMatch)
3888 // Registers are a valid target and have priority over symbols.
3889 ResTy = parseAnyRegister(Operands);
3890 if (ResTy != MatchOperand_NoMatch)
3893 const MCExpr *Expr = nullptr;
3894 if (Parser.parseExpression(Expr)) {
3895 // We have no way of knowing if a symbol was consumed so we must ParseFail
3896 return MatchOperand_ParseFail;
3899 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3900 return MatchOperand_Success;
3903 MipsAsmParser::OperandMatchResultTy
3904 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3905 MCAsmParser &Parser = getParser();
3906 const MCExpr *IdVal;
3907 // If the first token is '$' we may have register operand.
3908 if (Parser.getTok().is(AsmToken::Dollar))
3909 return MatchOperand_NoMatch;
3910 SMLoc S = Parser.getTok().getLoc();
3911 if (getParser().parseExpression(IdVal))
3912 return MatchOperand_ParseFail;
3913 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3914 assert(MCE && "Unexpected MCExpr type.");
3915 int64_t Val = MCE->getValue();
3916 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3917 Operands.push_back(MipsOperand::CreateImm(
3918 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3919 return MatchOperand_Success;
3922 MipsAsmParser::OperandMatchResultTy
3923 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3924 MCAsmParser &Parser = getParser();
3925 switch (getLexer().getKind()) {
3927 return MatchOperand_NoMatch;
3928 case AsmToken::LParen:
3929 case AsmToken::Plus:
3930 case AsmToken::Minus:
3931 case AsmToken::Integer:
3936 SMLoc S = Parser.getTok().getLoc();
3938 if (getParser().parseExpression(Expr))
3939 return MatchOperand_ParseFail;
3942 if (!Expr->evaluateAsAbsolute(Val)) {
3943 Error(S, "expected immediate value");
3944 return MatchOperand_ParseFail;
3947 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3948 // and because the CPU always adds one to the immediate field, the allowed
3949 // range becomes 1..4. We'll only check the range here and will deal
3950 // with the addition/subtraction when actually decoding/encoding
3952 if (Val < 1 || Val > 4) {
3953 Error(S, "immediate not in range (1..4)");
3954 return MatchOperand_ParseFail;
3958 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3959 return MatchOperand_Success;
3962 MipsAsmParser::OperandMatchResultTy
3963 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3964 MCAsmParser &Parser = getParser();
3965 SmallVector<unsigned, 10> Regs;
3967 unsigned PrevReg = Mips::NoRegister;
3968 bool RegRange = false;
3969 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3971 if (Parser.getTok().isNot(AsmToken::Dollar))
3972 return MatchOperand_ParseFail;
3974 SMLoc S = Parser.getTok().getLoc();
3975 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3976 SMLoc E = getLexer().getLoc();
3977 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3978 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3980 // Remove last register operand because registers from register range
3981 // should be inserted first.
3982 if (RegNo == Mips::RA) {
3983 Regs.push_back(RegNo);
3985 unsigned TmpReg = PrevReg + 1;
3986 while (TmpReg <= RegNo) {
3987 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3988 Error(E, "invalid register operand");
3989 return MatchOperand_ParseFail;
3993 Regs.push_back(TmpReg++);
3999 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4000 (RegNo != Mips::RA)) {
4001 Error(E, "$16 or $31 expected");
4002 return MatchOperand_ParseFail;
4003 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4004 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4005 Error(E, "invalid register operand");
4006 return MatchOperand_ParseFail;
4007 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4008 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4009 Error(E, "consecutive register numbers expected");
4010 return MatchOperand_ParseFail;
4013 Regs.push_back(RegNo);
4016 if (Parser.getTok().is(AsmToken::Minus))
4019 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4020 !Parser.getTok().isNot(AsmToken::Comma)) {
4021 Error(E, "',' or '-' expected");
4022 return MatchOperand_ParseFail;
4025 Lex(); // Consume comma or minus
4026 if (Parser.getTok().isNot(AsmToken::Dollar))
4032 SMLoc E = Parser.getTok().getLoc();
4033 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4034 parseMemOperand(Operands);
4035 return MatchOperand_Success;
4038 MipsAsmParser::OperandMatchResultTy
4039 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4040 MCAsmParser &Parser = getParser();
4042 SMLoc S = Parser.getTok().getLoc();
4043 if (parseAnyRegister(Operands) != MatchOperand_Success)
4044 return MatchOperand_ParseFail;
4046 SMLoc E = Parser.getTok().getLoc();
4047 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4048 unsigned Reg = Op.getGPR32Reg();
4049 Operands.pop_back();
4050 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4051 return MatchOperand_Success;
4054 MipsAsmParser::OperandMatchResultTy
4055 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4056 MCAsmParser &Parser = getParser();
4057 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4058 SmallVector<unsigned, 10> Regs;
4060 if (Parser.getTok().isNot(AsmToken::Dollar))
4061 return MatchOperand_ParseFail;
4063 SMLoc S = Parser.getTok().getLoc();
4065 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4066 return MatchOperand_ParseFail;
4068 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4069 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4070 Regs.push_back(RegNo);
4072 SMLoc E = Parser.getTok().getLoc();
4073 if (Parser.getTok().isNot(AsmToken::Comma)) {
4074 Error(E, "',' expected");
4075 return MatchOperand_ParseFail;
4081 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4082 return MatchOperand_ParseFail;
4084 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4085 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4086 Regs.push_back(RegNo);
4088 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4090 return MatchOperand_Success;
4093 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4095 MCSymbolRefExpr::VariantKind VK =
4096 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4097 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4098 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4099 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4100 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4101 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4102 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4103 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4104 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4105 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4106 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4107 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4108 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4109 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4110 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4111 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4112 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4113 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4114 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4115 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4116 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4117 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4118 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4119 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4120 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4121 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4122 .Default(MCSymbolRefExpr::VK_None);
4124 assert(VK != MCSymbolRefExpr::VK_None);
4129 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4131 /// ::= '(', register, ')'
4132 /// handle it before we iterate so we don't get tripped up by the lack of
4134 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4135 MCAsmParser &Parser = getParser();
4136 if (getLexer().is(AsmToken::LParen)) {
4138 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4140 if (parseOperand(Operands, Name)) {
4141 SMLoc Loc = getLexer().getLoc();
4142 Parser.eatToEndOfStatement();
4143 return Error(Loc, "unexpected token in argument list");
4145 if (Parser.getTok().isNot(AsmToken::RParen)) {
4146 SMLoc Loc = getLexer().getLoc();
4147 Parser.eatToEndOfStatement();
4148 return Error(Loc, "unexpected token, expected ')'");
4151 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4157 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4158 /// either one of these.
4159 /// ::= '[', register, ']'
4160 /// ::= '[', integer, ']'
4161 /// handle it before we iterate so we don't get tripped up by the lack of
4163 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4164 OperandVector &Operands) {
4165 MCAsmParser &Parser = getParser();
4166 if (getLexer().is(AsmToken::LBrac)) {
4168 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4170 if (parseOperand(Operands, Name)) {
4171 SMLoc Loc = getLexer().getLoc();
4172 Parser.eatToEndOfStatement();
4173 return Error(Loc, "unexpected token in argument list");
4175 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4176 SMLoc Loc = getLexer().getLoc();
4177 Parser.eatToEndOfStatement();
4178 return Error(Loc, "unexpected token, expected ']'");
4181 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4187 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4188 SMLoc NameLoc, OperandVector &Operands) {
4189 MCAsmParser &Parser = getParser();
4190 DEBUG(dbgs() << "ParseInstruction\n");
4192 // We have reached first instruction, module directive are now forbidden.
4193 getTargetStreamer().forbidModuleDirective();
4195 // Check if we have valid mnemonic
4196 if (!mnemonicIsValid(Name, 0)) {
4197 Parser.eatToEndOfStatement();
4198 return Error(NameLoc, "unknown instruction");
4200 // First operand in MCInst is instruction mnemonic.
4201 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4203 // Read the remaining operands.
4204 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4205 // Read the first operand.
4206 if (parseOperand(Operands, Name)) {
4207 SMLoc Loc = getLexer().getLoc();
4208 Parser.eatToEndOfStatement();
4209 return Error(Loc, "unexpected token in argument list");
4211 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4213 // AFAIK, parenthesis suffixes are never on the first operand
4215 while (getLexer().is(AsmToken::Comma)) {
4216 Parser.Lex(); // Eat the comma.
4217 // Parse and remember the operand.
4218 if (parseOperand(Operands, Name)) {
4219 SMLoc Loc = getLexer().getLoc();
4220 Parser.eatToEndOfStatement();
4221 return Error(Loc, "unexpected token in argument list");
4223 // Parse bracket and parenthesis suffixes before we iterate
4224 if (getLexer().is(AsmToken::LBrac)) {
4225 if (parseBracketSuffix(Name, Operands))
4227 } else if (getLexer().is(AsmToken::LParen) &&
4228 parseParenSuffix(Name, Operands))
4232 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4233 SMLoc Loc = getLexer().getLoc();
4234 Parser.eatToEndOfStatement();
4235 return Error(Loc, "unexpected token in argument list");
4237 Parser.Lex(); // Consume the EndOfStatement.
4241 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4242 MCAsmParser &Parser = getParser();
4243 SMLoc Loc = getLexer().getLoc();
4244 Parser.eatToEndOfStatement();
4245 return Error(Loc, ErrorMsg);
4248 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4249 return Error(Loc, ErrorMsg);
4252 bool MipsAsmParser::parseSetNoAtDirective() {
4253 MCAsmParser &Parser = getParser();
4254 // Line should look like: ".set noat".
4256 // Set the $at register to $0.
4257 AssemblerOptions.back()->setATRegIndex(0);
4259 Parser.Lex(); // Eat "noat".
4261 // If this is not the end of the statement, report an error.
4262 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4263 reportParseError("unexpected token, expected end of statement");
4267 getTargetStreamer().emitDirectiveSetNoAt();
4268 Parser.Lex(); // Consume the EndOfStatement.
4272 bool MipsAsmParser::parseSetAtDirective() {
4273 // Line can be: ".set at", which sets $at to $1
4274 // or ".set at=$reg", which sets $at to $reg.
4275 MCAsmParser &Parser = getParser();
4276 Parser.Lex(); // Eat "at".
4278 if (getLexer().is(AsmToken::EndOfStatement)) {
4279 // No register was specified, so we set $at to $1.
4280 AssemblerOptions.back()->setATRegIndex(1);
4282 getTargetStreamer().emitDirectiveSetAt();
4283 Parser.Lex(); // Consume the EndOfStatement.
4287 if (getLexer().isNot(AsmToken::Equal)) {
4288 reportParseError("unexpected token, expected equals sign");
4291 Parser.Lex(); // Eat "=".
4293 if (getLexer().isNot(AsmToken::Dollar)) {
4294 if (getLexer().is(AsmToken::EndOfStatement)) {
4295 reportParseError("no register specified");
4298 reportParseError("unexpected token, expected dollar sign '$'");
4302 Parser.Lex(); // Eat "$".
4304 // Find out what "reg" is.
4306 const AsmToken &Reg = Parser.getTok();
4307 if (Reg.is(AsmToken::Identifier)) {
4308 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4309 } else if (Reg.is(AsmToken::Integer)) {
4310 AtRegNo = Reg.getIntVal();
4312 reportParseError("unexpected token, expected identifier or integer");
4316 // Check if $reg is a valid register. If it is, set $at to $reg.
4317 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4318 reportParseError("invalid register");
4321 Parser.Lex(); // Eat "reg".
4323 // If this is not the end of the statement, report an error.
4324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4325 reportParseError("unexpected token, expected end of statement");
4329 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4331 Parser.Lex(); // Consume the EndOfStatement.
4335 bool MipsAsmParser::parseSetReorderDirective() {
4336 MCAsmParser &Parser = getParser();
4338 // If this is not the end of the statement, report an error.
4339 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4340 reportParseError("unexpected token, expected end of statement");
4343 AssemblerOptions.back()->setReorder();
4344 getTargetStreamer().emitDirectiveSetReorder();
4345 Parser.Lex(); // Consume the EndOfStatement.
4349 bool MipsAsmParser::parseSetNoReorderDirective() {
4350 MCAsmParser &Parser = getParser();
4352 // If this is not the end of the statement, report an error.
4353 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4354 reportParseError("unexpected token, expected end of statement");
4357 AssemblerOptions.back()->setNoReorder();
4358 getTargetStreamer().emitDirectiveSetNoReorder();
4359 Parser.Lex(); // Consume the EndOfStatement.
4363 bool MipsAsmParser::parseSetMacroDirective() {
4364 MCAsmParser &Parser = getParser();
4366 // If this is not the end of the statement, report an error.
4367 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4368 reportParseError("unexpected token, expected end of statement");
4371 AssemblerOptions.back()->setMacro();
4372 getTargetStreamer().emitDirectiveSetMacro();
4373 Parser.Lex(); // Consume the EndOfStatement.
4377 bool MipsAsmParser::parseSetNoMacroDirective() {
4378 MCAsmParser &Parser = getParser();
4380 // If this is not the end of the statement, report an error.
4381 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4382 reportParseError("unexpected token, expected end of statement");
4385 if (AssemblerOptions.back()->isReorder()) {
4386 reportParseError("`noreorder' must be set before `nomacro'");
4389 AssemblerOptions.back()->setNoMacro();
4390 getTargetStreamer().emitDirectiveSetNoMacro();
4391 Parser.Lex(); // Consume the EndOfStatement.
4395 bool MipsAsmParser::parseSetMsaDirective() {
4396 MCAsmParser &Parser = getParser();
4399 // If this is not the end of the statement, report an error.
4400 if (getLexer().isNot(AsmToken::EndOfStatement))
4401 return reportParseError("unexpected token, expected end of statement");
4403 setFeatureBits(Mips::FeatureMSA, "msa");
4404 getTargetStreamer().emitDirectiveSetMsa();
4408 bool MipsAsmParser::parseSetNoMsaDirective() {
4409 MCAsmParser &Parser = getParser();
4412 // If this is not the end of the statement, report an error.
4413 if (getLexer().isNot(AsmToken::EndOfStatement))
4414 return reportParseError("unexpected token, expected end of statement");
4416 clearFeatureBits(Mips::FeatureMSA, "msa");
4417 getTargetStreamer().emitDirectiveSetNoMsa();
4421 bool MipsAsmParser::parseSetNoDspDirective() {
4422 MCAsmParser &Parser = getParser();
4423 Parser.Lex(); // Eat "nodsp".
4425 // If this is not the end of the statement, report an error.
4426 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4427 reportParseError("unexpected token, expected end of statement");
4431 clearFeatureBits(Mips::FeatureDSP, "dsp");
4432 getTargetStreamer().emitDirectiveSetNoDsp();
4436 bool MipsAsmParser::parseSetMips16Directive() {
4437 MCAsmParser &Parser = getParser();
4438 Parser.Lex(); // Eat "mips16".
4440 // If this is not the end of the statement, report an error.
4441 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4442 reportParseError("unexpected token, expected end of statement");
4446 setFeatureBits(Mips::FeatureMips16, "mips16");
4447 getTargetStreamer().emitDirectiveSetMips16();
4448 Parser.Lex(); // Consume the EndOfStatement.
4452 bool MipsAsmParser::parseSetNoMips16Directive() {
4453 MCAsmParser &Parser = getParser();
4454 Parser.Lex(); // Eat "nomips16".
4456 // If this is not the end of the statement, report an error.
4457 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4458 reportParseError("unexpected token, expected end of statement");
4462 clearFeatureBits(Mips::FeatureMips16, "mips16");
4463 getTargetStreamer().emitDirectiveSetNoMips16();
4464 Parser.Lex(); // Consume the EndOfStatement.
4468 bool MipsAsmParser::parseSetFpDirective() {
4469 MCAsmParser &Parser = getParser();
4470 MipsABIFlagsSection::FpABIKind FpAbiVal;
4471 // Line can be: .set fp=32
4474 Parser.Lex(); // Eat fp token
4475 AsmToken Tok = Parser.getTok();
4476 if (Tok.isNot(AsmToken::Equal)) {
4477 reportParseError("unexpected token, expected equals sign '='");
4480 Parser.Lex(); // Eat '=' token.
4481 Tok = Parser.getTok();
4483 if (!parseFpABIValue(FpAbiVal, ".set"))
4486 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4487 reportParseError("unexpected token, expected end of statement");
4490 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4491 Parser.Lex(); // Consume the EndOfStatement.
4495 bool MipsAsmParser::parseSetOddSPRegDirective() {
4496 MCAsmParser &Parser = getParser();
4498 Parser.Lex(); // Eat "oddspreg".
4499 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4500 reportParseError("unexpected token, expected end of statement");
4504 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4505 getTargetStreamer().emitDirectiveSetOddSPReg();
4509 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4510 MCAsmParser &Parser = getParser();
4512 Parser.Lex(); // Eat "nooddspreg".
4513 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4514 reportParseError("unexpected token, expected end of statement");
4518 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4519 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4523 bool MipsAsmParser::parseSetPopDirective() {
4524 MCAsmParser &Parser = getParser();
4525 SMLoc Loc = getLexer().getLoc();
4528 if (getLexer().isNot(AsmToken::EndOfStatement))
4529 return reportParseError("unexpected token, expected end of statement");
4531 // Always keep an element on the options "stack" to prevent the user
4532 // from changing the initial options. This is how we remember them.
4533 if (AssemblerOptions.size() == 2)
4534 return reportParseError(Loc, ".set pop with no .set push");
4536 AssemblerOptions.pop_back();
4537 setAvailableFeatures(
4538 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4539 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4541 getTargetStreamer().emitDirectiveSetPop();
4545 bool MipsAsmParser::parseSetPushDirective() {
4546 MCAsmParser &Parser = getParser();
4548 if (getLexer().isNot(AsmToken::EndOfStatement))
4549 return reportParseError("unexpected token, expected end of statement");
4551 // Create a copy of the current assembler options environment and push it.
4552 AssemblerOptions.push_back(
4553 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4555 getTargetStreamer().emitDirectiveSetPush();
4559 bool MipsAsmParser::parseSetSoftFloatDirective() {
4560 MCAsmParser &Parser = getParser();
4562 if (getLexer().isNot(AsmToken::EndOfStatement))
4563 return reportParseError("unexpected token, expected end of statement");
4565 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4566 getTargetStreamer().emitDirectiveSetSoftFloat();
4570 bool MipsAsmParser::parseSetHardFloatDirective() {
4571 MCAsmParser &Parser = getParser();
4573 if (getLexer().isNot(AsmToken::EndOfStatement))
4574 return reportParseError("unexpected token, expected end of statement");
4576 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4577 getTargetStreamer().emitDirectiveSetHardFloat();
4581 bool MipsAsmParser::parseSetAssignment() {
4583 const MCExpr *Value;
4584 MCAsmParser &Parser = getParser();
4586 if (Parser.parseIdentifier(Name))
4587 reportParseError("expected identifier after .set");
4589 if (getLexer().isNot(AsmToken::Comma))
4590 return reportParseError("unexpected token, expected comma");
4593 if (Parser.parseExpression(Value))
4594 return reportParseError("expected valid expression after comma");
4596 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4597 Sym->setVariableValue(Value);
4602 bool MipsAsmParser::parseSetMips0Directive() {
4603 MCAsmParser &Parser = getParser();
4605 if (getLexer().isNot(AsmToken::EndOfStatement))
4606 return reportParseError("unexpected token, expected end of statement");
4608 // Reset assembler options to their initial values.
4609 setAvailableFeatures(
4610 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4611 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4612 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4614 getTargetStreamer().emitDirectiveSetMips0();
4618 bool MipsAsmParser::parseSetArchDirective() {
4619 MCAsmParser &Parser = getParser();
4621 if (getLexer().isNot(AsmToken::Equal))
4622 return reportParseError("unexpected token, expected equals sign");
4626 if (Parser.parseIdentifier(Arch))
4627 return reportParseError("expected arch identifier");
4629 StringRef ArchFeatureName =
4630 StringSwitch<StringRef>(Arch)
4631 .Case("mips1", "mips1")
4632 .Case("mips2", "mips2")
4633 .Case("mips3", "mips3")
4634 .Case("mips4", "mips4")
4635 .Case("mips5", "mips5")
4636 .Case("mips32", "mips32")
4637 .Case("mips32r2", "mips32r2")
4638 .Case("mips32r3", "mips32r3")
4639 .Case("mips32r5", "mips32r5")
4640 .Case("mips32r6", "mips32r6")
4641 .Case("mips64", "mips64")
4642 .Case("mips64r2", "mips64r2")
4643 .Case("mips64r3", "mips64r3")
4644 .Case("mips64r5", "mips64r5")
4645 .Case("mips64r6", "mips64r6")
4646 .Case("cnmips", "cnmips")
4647 .Case("r4000", "mips3") // This is an implementation of Mips3.
4650 if (ArchFeatureName.empty())
4651 return reportParseError("unsupported architecture");
4653 selectArch(ArchFeatureName);
4654 getTargetStreamer().emitDirectiveSetArch(Arch);
4658 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4659 MCAsmParser &Parser = getParser();
4661 if (getLexer().isNot(AsmToken::EndOfStatement))
4662 return reportParseError("unexpected token, expected end of statement");
4666 llvm_unreachable("Unimplemented feature");
4667 case Mips::FeatureDSP:
4668 setFeatureBits(Mips::FeatureDSP, "dsp");
4669 getTargetStreamer().emitDirectiveSetDsp();
4671 case Mips::FeatureMicroMips:
4672 getTargetStreamer().emitDirectiveSetMicroMips();
4674 case Mips::FeatureMips1:
4675 selectArch("mips1");
4676 getTargetStreamer().emitDirectiveSetMips1();
4678 case Mips::FeatureMips2:
4679 selectArch("mips2");
4680 getTargetStreamer().emitDirectiveSetMips2();
4682 case Mips::FeatureMips3:
4683 selectArch("mips3");
4684 getTargetStreamer().emitDirectiveSetMips3();
4686 case Mips::FeatureMips4:
4687 selectArch("mips4");
4688 getTargetStreamer().emitDirectiveSetMips4();
4690 case Mips::FeatureMips5:
4691 selectArch("mips5");
4692 getTargetStreamer().emitDirectiveSetMips5();
4694 case Mips::FeatureMips32:
4695 selectArch("mips32");
4696 getTargetStreamer().emitDirectiveSetMips32();
4698 case Mips::FeatureMips32r2:
4699 selectArch("mips32r2");
4700 getTargetStreamer().emitDirectiveSetMips32R2();
4702 case Mips::FeatureMips32r3:
4703 selectArch("mips32r3");
4704 getTargetStreamer().emitDirectiveSetMips32R3();
4706 case Mips::FeatureMips32r5:
4707 selectArch("mips32r5");
4708 getTargetStreamer().emitDirectiveSetMips32R5();
4710 case Mips::FeatureMips32r6:
4711 selectArch("mips32r6");
4712 getTargetStreamer().emitDirectiveSetMips32R6();
4714 case Mips::FeatureMips64:
4715 selectArch("mips64");
4716 getTargetStreamer().emitDirectiveSetMips64();
4718 case Mips::FeatureMips64r2:
4719 selectArch("mips64r2");
4720 getTargetStreamer().emitDirectiveSetMips64R2();
4722 case Mips::FeatureMips64r3:
4723 selectArch("mips64r3");
4724 getTargetStreamer().emitDirectiveSetMips64R3();
4726 case Mips::FeatureMips64r5:
4727 selectArch("mips64r5");
4728 getTargetStreamer().emitDirectiveSetMips64R5();
4730 case Mips::FeatureMips64r6:
4731 selectArch("mips64r6");
4732 getTargetStreamer().emitDirectiveSetMips64R6();
4738 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4739 MCAsmParser &Parser = getParser();
4740 if (getLexer().isNot(AsmToken::Comma)) {
4741 SMLoc Loc = getLexer().getLoc();
4742 Parser.eatToEndOfStatement();
4743 return Error(Loc, ErrorStr);
4746 Parser.Lex(); // Eat the comma.
4750 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4751 if (AssemblerOptions.back()->isReorder())
4752 Warning(Loc, ".cpload should be inside a noreorder section");
4754 if (inMips16Mode()) {
4755 reportParseError(".cpload is not supported in Mips16 mode");
4759 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4760 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4761 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4762 reportParseError("expected register containing function address");
4766 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4767 if (!RegOpnd.isGPRAsmReg()) {
4768 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4772 // If this is not the end of the statement, report an error.
4773 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4774 reportParseError("unexpected token, expected end of statement");
4778 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4782 bool MipsAsmParser::parseDirectiveCPSetup() {
4783 MCAsmParser &Parser = getParser();
4786 bool SaveIsReg = true;
4788 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4789 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4790 if (ResTy == MatchOperand_NoMatch) {
4791 reportParseError("expected register containing function address");
4792 Parser.eatToEndOfStatement();
4796 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4797 if (!FuncRegOpnd.isGPRAsmReg()) {
4798 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4799 Parser.eatToEndOfStatement();
4803 FuncReg = FuncRegOpnd.getGPR32Reg();
4806 if (!eatComma("unexpected token, expected comma"))
4809 ResTy = parseAnyRegister(TmpReg);
4810 if (ResTy == MatchOperand_NoMatch) {
4811 const AsmToken &Tok = Parser.getTok();
4812 if (Tok.is(AsmToken::Integer)) {
4813 Save = Tok.getIntVal();
4817 reportParseError("expected save register or stack offset");
4818 Parser.eatToEndOfStatement();
4822 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4823 if (!SaveOpnd.isGPRAsmReg()) {
4824 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4825 Parser.eatToEndOfStatement();
4828 Save = SaveOpnd.getGPR32Reg();
4831 if (!eatComma("unexpected token, expected comma"))
4835 if (Parser.parseExpression(Expr)) {
4836 reportParseError("expected expression");
4840 if (Expr->getKind() != MCExpr::SymbolRef) {
4841 reportParseError("expected symbol");
4844 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4846 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4851 bool MipsAsmParser::parseDirectiveNaN() {
4852 MCAsmParser &Parser = getParser();
4853 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4854 const AsmToken &Tok = Parser.getTok();
4856 if (Tok.getString() == "2008") {
4858 getTargetStreamer().emitDirectiveNaN2008();
4860 } else if (Tok.getString() == "legacy") {
4862 getTargetStreamer().emitDirectiveNaNLegacy();
4866 // If we don't recognize the option passed to the .nan
4867 // directive (e.g. no option or unknown option), emit an error.
4868 reportParseError("invalid option in .nan directive");
4872 bool MipsAsmParser::parseDirectiveSet() {
4873 MCAsmParser &Parser = getParser();
4874 // Get the next token.
4875 const AsmToken &Tok = Parser.getTok();
4877 if (Tok.getString() == "noat") {
4878 return parseSetNoAtDirective();
4879 } else if (Tok.getString() == "at") {
4880 return parseSetAtDirective();
4881 } else if (Tok.getString() == "arch") {
4882 return parseSetArchDirective();
4883 } else if (Tok.getString() == "fp") {
4884 return parseSetFpDirective();
4885 } else if (Tok.getString() == "oddspreg") {
4886 return parseSetOddSPRegDirective();
4887 } else if (Tok.getString() == "nooddspreg") {
4888 return parseSetNoOddSPRegDirective();
4889 } else if (Tok.getString() == "pop") {
4890 return parseSetPopDirective();
4891 } else if (Tok.getString() == "push") {
4892 return parseSetPushDirective();
4893 } else if (Tok.getString() == "reorder") {
4894 return parseSetReorderDirective();
4895 } else if (Tok.getString() == "noreorder") {
4896 return parseSetNoReorderDirective();
4897 } else if (Tok.getString() == "macro") {
4898 return parseSetMacroDirective();
4899 } else if (Tok.getString() == "nomacro") {
4900 return parseSetNoMacroDirective();
4901 } else if (Tok.getString() == "mips16") {
4902 return parseSetMips16Directive();
4903 } else if (Tok.getString() == "nomips16") {
4904 return parseSetNoMips16Directive();
4905 } else if (Tok.getString() == "nomicromips") {
4906 getTargetStreamer().emitDirectiveSetNoMicroMips();
4907 Parser.eatToEndOfStatement();
4909 } else if (Tok.getString() == "micromips") {
4910 return parseSetFeature(Mips::FeatureMicroMips);
4911 } else if (Tok.getString() == "mips0") {
4912 return parseSetMips0Directive();
4913 } else if (Tok.getString() == "mips1") {
4914 return parseSetFeature(Mips::FeatureMips1);
4915 } else if (Tok.getString() == "mips2") {
4916 return parseSetFeature(Mips::FeatureMips2);
4917 } else if (Tok.getString() == "mips3") {
4918 return parseSetFeature(Mips::FeatureMips3);
4919 } else if (Tok.getString() == "mips4") {
4920 return parseSetFeature(Mips::FeatureMips4);
4921 } else if (Tok.getString() == "mips5") {
4922 return parseSetFeature(Mips::FeatureMips5);
4923 } else if (Tok.getString() == "mips32") {
4924 return parseSetFeature(Mips::FeatureMips32);
4925 } else if (Tok.getString() == "mips32r2") {
4926 return parseSetFeature(Mips::FeatureMips32r2);
4927 } else if (Tok.getString() == "mips32r3") {
4928 return parseSetFeature(Mips::FeatureMips32r3);
4929 } else if (Tok.getString() == "mips32r5") {
4930 return parseSetFeature(Mips::FeatureMips32r5);
4931 } else if (Tok.getString() == "mips32r6") {
4932 return parseSetFeature(Mips::FeatureMips32r6);
4933 } else if (Tok.getString() == "mips64") {
4934 return parseSetFeature(Mips::FeatureMips64);
4935 } else if (Tok.getString() == "mips64r2") {
4936 return parseSetFeature(Mips::FeatureMips64r2);
4937 } else if (Tok.getString() == "mips64r3") {
4938 return parseSetFeature(Mips::FeatureMips64r3);
4939 } else if (Tok.getString() == "mips64r5") {
4940 return parseSetFeature(Mips::FeatureMips64r5);
4941 } else if (Tok.getString() == "mips64r6") {
4942 return parseSetFeature(Mips::FeatureMips64r6);
4943 } else if (Tok.getString() == "dsp") {
4944 return parseSetFeature(Mips::FeatureDSP);
4945 } else if (Tok.getString() == "nodsp") {
4946 return parseSetNoDspDirective();
4947 } else if (Tok.getString() == "msa") {
4948 return parseSetMsaDirective();
4949 } else if (Tok.getString() == "nomsa") {
4950 return parseSetNoMsaDirective();
4951 } else if (Tok.getString() == "softfloat") {
4952 return parseSetSoftFloatDirective();
4953 } else if (Tok.getString() == "hardfloat") {
4954 return parseSetHardFloatDirective();
4956 // It is just an identifier, look for an assignment.
4957 parseSetAssignment();
4964 /// parseDataDirective
4965 /// ::= .word [ expression (, expression)* ]
4966 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4967 MCAsmParser &Parser = getParser();
4968 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4970 const MCExpr *Value;
4971 if (getParser().parseExpression(Value))
4974 getParser().getStreamer().EmitValue(Value, Size);
4976 if (getLexer().is(AsmToken::EndOfStatement))
4979 if (getLexer().isNot(AsmToken::Comma))
4980 return Error(L, "unexpected token, expected comma");
4989 /// parseDirectiveGpWord
4990 /// ::= .gpword local_sym
4991 bool MipsAsmParser::parseDirectiveGpWord() {
4992 MCAsmParser &Parser = getParser();
4993 const MCExpr *Value;
4994 // EmitGPRel32Value requires an expression, so we are using base class
4995 // method to evaluate the expression.
4996 if (getParser().parseExpression(Value))
4998 getParser().getStreamer().EmitGPRel32Value(Value);
5000 if (getLexer().isNot(AsmToken::EndOfStatement))
5001 return Error(getLexer().getLoc(),
5002 "unexpected token, expected end of statement");
5003 Parser.Lex(); // Eat EndOfStatement token.
5007 /// parseDirectiveGpDWord
5008 /// ::= .gpdword local_sym
5009 bool MipsAsmParser::parseDirectiveGpDWord() {
5010 MCAsmParser &Parser = getParser();
5011 const MCExpr *Value;
5012 // EmitGPRel64Value requires an expression, so we are using base class
5013 // method to evaluate the expression.
5014 if (getParser().parseExpression(Value))
5016 getParser().getStreamer().EmitGPRel64Value(Value);
5018 if (getLexer().isNot(AsmToken::EndOfStatement))
5019 return Error(getLexer().getLoc(),
5020 "unexpected token, expected end of statement");
5021 Parser.Lex(); // Eat EndOfStatement token.
5025 bool MipsAsmParser::parseDirectiveOption() {
5026 MCAsmParser &Parser = getParser();
5027 // Get the option token.
5028 AsmToken Tok = Parser.getTok();
5029 // At the moment only identifiers are supported.
5030 if (Tok.isNot(AsmToken::Identifier)) {
5031 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5032 Parser.eatToEndOfStatement();
5036 StringRef Option = Tok.getIdentifier();
5038 if (Option == "pic0") {
5039 // MipsAsmParser needs to know if the current PIC mode changes.
5040 IsPicEnabled = false;
5042 getTargetStreamer().emitDirectiveOptionPic0();
5044 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5045 Error(Parser.getTok().getLoc(),
5046 "unexpected token, expected end of statement");
5047 Parser.eatToEndOfStatement();
5052 if (Option == "pic2") {
5053 // MipsAsmParser needs to know if the current PIC mode changes.
5054 IsPicEnabled = true;
5056 getTargetStreamer().emitDirectiveOptionPic2();
5058 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5059 Error(Parser.getTok().getLoc(),
5060 "unexpected token, expected end of statement");
5061 Parser.eatToEndOfStatement();
5067 Warning(Parser.getTok().getLoc(),
5068 "unknown option, expected 'pic0' or 'pic2'");
5069 Parser.eatToEndOfStatement();
5073 /// parseInsnDirective
5075 bool MipsAsmParser::parseInsnDirective() {
5076 // If this is not the end of the statement, report an error.
5077 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5078 reportParseError("unexpected token, expected end of statement");
5082 // The actual label marking happens in
5083 // MipsELFStreamer::createPendingLabelRelocs().
5084 getTargetStreamer().emitDirectiveInsn();
5086 getParser().Lex(); // Eat EndOfStatement token.
5090 /// parseDirectiveModule
5091 /// ::= .module oddspreg
5092 /// ::= .module nooddspreg
5093 /// ::= .module fp=value
5094 /// ::= .module softfloat
5095 /// ::= .module hardfloat
5096 bool MipsAsmParser::parseDirectiveModule() {
5097 MCAsmParser &Parser = getParser();
5098 MCAsmLexer &Lexer = getLexer();
5099 SMLoc L = Lexer.getLoc();
5101 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5102 // TODO : get a better message.
5103 reportParseError(".module directive must appear before any code");
5108 if (Parser.parseIdentifier(Option)) {
5109 reportParseError("expected .module option identifier");
5113 if (Option == "oddspreg") {
5114 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5116 // Synchronize the abiflags information with the FeatureBits information we
5118 getTargetStreamer().updateABIInfo(*this);
5120 // If printing assembly, use the recently updated abiflags information.
5121 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5122 // emitted at the end).
5123 getTargetStreamer().emitDirectiveModuleOddSPReg();
5125 // If this is not the end of the statement, report an error.
5126 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5127 reportParseError("unexpected token, expected end of statement");
5131 return false; // parseDirectiveModule has finished successfully.
5132 } else if (Option == "nooddspreg") {
5134 Error(L, "'.module nooddspreg' requires the O32 ABI");
5138 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5140 // Synchronize the abiflags information with the FeatureBits information we
5142 getTargetStreamer().updateABIInfo(*this);
5144 // If printing assembly, use the recently updated abiflags information.
5145 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5146 // emitted at the end).
5147 getTargetStreamer().emitDirectiveModuleOddSPReg();
5149 // If this is not the end of the statement, report an error.
5150 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5151 reportParseError("unexpected token, expected end of statement");
5155 return false; // parseDirectiveModule has finished successfully.
5156 } else if (Option == "fp") {
5157 return parseDirectiveModuleFP();
5158 } else if (Option == "softfloat") {
5159 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5161 // Synchronize the ABI Flags information with the FeatureBits information we
5163 getTargetStreamer().updateABIInfo(*this);
5165 // If printing assembly, use the recently updated ABI Flags information.
5166 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5168 getTargetStreamer().emitDirectiveModuleSoftFloat();
5170 // If this is not the end of the statement, report an error.
5171 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5172 reportParseError("unexpected token, expected end of statement");
5176 return false; // parseDirectiveModule has finished successfully.
5177 } else if (Option == "hardfloat") {
5178 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5180 // Synchronize the ABI Flags information with the FeatureBits information we
5182 getTargetStreamer().updateABIInfo(*this);
5184 // If printing assembly, use the recently updated ABI Flags information.
5185 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5187 getTargetStreamer().emitDirectiveModuleHardFloat();
5189 // If this is not the end of the statement, report an error.
5190 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5191 reportParseError("unexpected token, expected end of statement");
5195 return false; // parseDirectiveModule has finished successfully.
5197 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5201 /// parseDirectiveModuleFP
5205 bool MipsAsmParser::parseDirectiveModuleFP() {
5206 MCAsmParser &Parser = getParser();
5207 MCAsmLexer &Lexer = getLexer();
5209 if (Lexer.isNot(AsmToken::Equal)) {
5210 reportParseError("unexpected token, expected equals sign '='");
5213 Parser.Lex(); // Eat '=' token.
5215 MipsABIFlagsSection::FpABIKind FpABI;
5216 if (!parseFpABIValue(FpABI, ".module"))
5219 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5220 reportParseError("unexpected token, expected end of statement");
5224 // Synchronize the abiflags information with the FeatureBits information we
5226 getTargetStreamer().updateABIInfo(*this);
5228 // If printing assembly, use the recently updated abiflags information.
5229 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5230 // emitted at the end).
5231 getTargetStreamer().emitDirectiveModuleFP();
5233 Parser.Lex(); // Consume the EndOfStatement.
5237 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5238 StringRef Directive) {
5239 MCAsmParser &Parser = getParser();
5240 MCAsmLexer &Lexer = getLexer();
5241 bool ModuleLevelOptions = Directive == ".module";
5243 if (Lexer.is(AsmToken::Identifier)) {
5244 StringRef Value = Parser.getTok().getString();
5247 if (Value != "xx") {
5248 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5253 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5257 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5258 if (ModuleLevelOptions) {
5259 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5260 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5262 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5263 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5268 if (Lexer.is(AsmToken::Integer)) {
5269 unsigned Value = Parser.getTok().getIntVal();
5272 if (Value != 32 && Value != 64) {
5273 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5279 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5283 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5284 if (ModuleLevelOptions) {
5285 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5286 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5288 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5289 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5292 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5293 if (ModuleLevelOptions) {
5294 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5295 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5297 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5298 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5308 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5309 MCAsmParser &Parser = getParser();
5310 StringRef IDVal = DirectiveID.getString();
5312 if (IDVal == ".cpload")
5313 return parseDirectiveCpLoad(DirectiveID.getLoc());
5314 if (IDVal == ".dword") {
5315 parseDataDirective(8, DirectiveID.getLoc());
5318 if (IDVal == ".ent") {
5319 StringRef SymbolName;
5321 if (Parser.parseIdentifier(SymbolName)) {
5322 reportParseError("expected identifier after .ent");
5326 // There's an undocumented extension that allows an integer to
5327 // follow the name of the procedure which AFAICS is ignored by GAS.
5328 // Example: .ent foo,2
5329 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5330 if (getLexer().isNot(AsmToken::Comma)) {
5331 // Even though we accept this undocumented extension for compatibility
5332 // reasons, the additional integer argument does not actually change
5333 // the behaviour of the '.ent' directive, so we would like to discourage
5334 // its use. We do this by not referring to the extended version in
5335 // error messages which are not directly related to its use.
5336 reportParseError("unexpected token, expected end of statement");
5339 Parser.Lex(); // Eat the comma.
5340 const MCExpr *DummyNumber;
5341 int64_t DummyNumberVal;
5342 // If the user was explicitly trying to use the extended version,
5343 // we still give helpful extension-related error messages.
5344 if (Parser.parseExpression(DummyNumber)) {
5345 reportParseError("expected number after comma");
5348 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5349 reportParseError("expected an absolute expression after comma");
5354 // If this is not the end of the statement, report an error.
5355 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5356 reportParseError("unexpected token, expected end of statement");
5360 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5362 getTargetStreamer().emitDirectiveEnt(*Sym);
5367 if (IDVal == ".end") {
5368 StringRef SymbolName;
5370 if (Parser.parseIdentifier(SymbolName)) {
5371 reportParseError("expected identifier after .end");
5375 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5376 reportParseError("unexpected token, expected end of statement");
5380 if (CurrentFn == nullptr) {
5381 reportParseError(".end used without .ent");
5385 if ((SymbolName != CurrentFn->getName())) {
5386 reportParseError(".end symbol does not match .ent symbol");
5390 getTargetStreamer().emitDirectiveEnd(SymbolName);
5391 CurrentFn = nullptr;
5395 if (IDVal == ".frame") {
5396 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5397 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5398 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5399 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5400 reportParseError("expected stack register");
5404 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5405 if (!StackRegOpnd.isGPRAsmReg()) {
5406 reportParseError(StackRegOpnd.getStartLoc(),
5407 "expected general purpose register");
5410 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5412 if (Parser.getTok().is(AsmToken::Comma))
5415 reportParseError("unexpected token, expected comma");
5419 // Parse the frame size.
5420 const MCExpr *FrameSize;
5421 int64_t FrameSizeVal;
5423 if (Parser.parseExpression(FrameSize)) {
5424 reportParseError("expected frame size value");
5428 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5429 reportParseError("frame size not an absolute expression");
5433 if (Parser.getTok().is(AsmToken::Comma))
5436 reportParseError("unexpected token, expected comma");
5440 // Parse the return register.
5442 ResTy = parseAnyRegister(TmpReg);
5443 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5444 reportParseError("expected return register");
5448 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5449 if (!ReturnRegOpnd.isGPRAsmReg()) {
5450 reportParseError(ReturnRegOpnd.getStartLoc(),
5451 "expected general purpose register");
5455 // If this is not the end of the statement, report an error.
5456 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5457 reportParseError("unexpected token, expected end of statement");
5461 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5462 ReturnRegOpnd.getGPR32Reg());
5466 if (IDVal == ".set") {
5467 return parseDirectiveSet();
5470 if (IDVal == ".mask" || IDVal == ".fmask") {
5471 // .mask bitmask, frame_offset
5472 // bitmask: One bit for each register used.
5473 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5474 // first register is expected to be saved.
5476 // .mask 0x80000000, -4
5477 // .fmask 0x80000000, -4
5480 // Parse the bitmask
5481 const MCExpr *BitMask;
5484 if (Parser.parseExpression(BitMask)) {
5485 reportParseError("expected bitmask value");
5489 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5490 reportParseError("bitmask not an absolute expression");
5494 if (Parser.getTok().is(AsmToken::Comma))
5497 reportParseError("unexpected token, expected comma");
5501 // Parse the frame_offset
5502 const MCExpr *FrameOffset;
5503 int64_t FrameOffsetVal;
5505 if (Parser.parseExpression(FrameOffset)) {
5506 reportParseError("expected frame offset value");
5510 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5511 reportParseError("frame offset not an absolute expression");
5515 // If this is not the end of the statement, report an error.
5516 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5517 reportParseError("unexpected token, expected end of statement");
5521 if (IDVal == ".mask")
5522 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5524 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5528 if (IDVal == ".nan")
5529 return parseDirectiveNaN();
5531 if (IDVal == ".gpword") {
5532 parseDirectiveGpWord();
5536 if (IDVal == ".gpdword") {
5537 parseDirectiveGpDWord();
5541 if (IDVal == ".word") {
5542 parseDataDirective(4, DirectiveID.getLoc());
5546 if (IDVal == ".option")
5547 return parseDirectiveOption();
5549 if (IDVal == ".abicalls") {
5550 getTargetStreamer().emitDirectiveAbiCalls();
5551 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5552 Error(Parser.getTok().getLoc(),
5553 "unexpected token, expected end of statement");
5555 Parser.eatToEndOfStatement();
5560 if (IDVal == ".cpsetup")
5561 return parseDirectiveCPSetup();
5563 if (IDVal == ".module")
5564 return parseDirectiveModule();
5566 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5567 return parseInternalDirectiveReallowModule();
5569 if (IDVal == ".insn")
5570 return parseInsnDirective();
5575 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5576 // If this is not the end of the statement, report an error.
5577 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5578 reportParseError("unexpected token, expected end of statement");
5582 getTargetStreamer().reallowModuleDirective();
5584 getParser().Lex(); // Eat EndOfStatement token.
5588 extern "C" void LLVMInitializeMipsAsmParser() {
5589 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5590 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5591 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5592 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5595 #define GET_REGISTER_MATCHER
5596 #define GET_MATCHER_IMPLEMENTATION
5597 #include "MipsGenAsmMatcher.inc"