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(Triple(sti.getTargetTriple()),
379 sti.getCPU(), Options)) {
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 Triple TheTriple(sti.getTargetTriple());
406 if ((TheTriple.getArch() == Triple::mips) ||
407 (TheTriple.getArch() == Triple::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 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
951 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
952 getMemBase()->isGPRAsmReg();
954 bool isMemWithGRPMM16Base() const {
955 return isMem() && getMemBase()->isMM16AsmReg();
957 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
958 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
959 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
961 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
962 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
963 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
964 && (getMemBase()->getGPR32Reg() == Mips::SP);
966 bool isRegList16() const {
970 int Size = RegList.List->size();
971 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
972 RegList.List->back() != Mips::RA)
975 int PrevReg = *RegList.List->begin();
976 for (int i = 1; i < Size - 1; i++) {
977 int Reg = (*(RegList.List))[i];
978 if ( Reg != PrevReg + 1)
985 bool isInvNum() const { return Kind == k_Immediate; }
986 bool isLSAImm() const {
987 if (!isConstantImm())
989 int64_t Val = getConstantImm();
990 return 1 <= Val && Val <= 4;
992 bool isRegList() const { return Kind == k_RegList; }
993 bool isMovePRegPair() const {
994 if (Kind != k_RegList || RegList.List->size() != 2)
997 unsigned R0 = RegList.List->front();
998 unsigned R1 = RegList.List->back();
1000 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1001 (R0 == Mips::A1 && R1 == Mips::A3) ||
1002 (R0 == Mips::A2 && R1 == Mips::A3) ||
1003 (R0 == Mips::A0 && R1 == Mips::S5) ||
1004 (R0 == Mips::A0 && R1 == Mips::S6) ||
1005 (R0 == Mips::A0 && R1 == Mips::A1) ||
1006 (R0 == Mips::A0 && R1 == Mips::A2) ||
1007 (R0 == Mips::A0 && R1 == Mips::A3))
1013 StringRef getToken() const {
1014 assert(Kind == k_Token && "Invalid access!");
1015 return StringRef(Tok.Data, Tok.Length);
1017 bool isRegPair() const { return Kind == k_RegPair; }
1019 unsigned getReg() const override {
1020 // As a special case until we sort out the definition of div/divu, pretend
1021 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1022 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1023 RegIdx.Kind & RegKind_GPR)
1024 return getGPR32Reg(); // FIXME: GPR64 too
1026 assert(Kind == k_PhysRegister && "Invalid access!");
1030 const MCExpr *getImm() const {
1031 assert((Kind == k_Immediate) && "Invalid access!");
1035 int64_t getConstantImm() const {
1036 const MCExpr *Val = getImm();
1037 return static_cast<const MCConstantExpr *>(Val)->getValue();
1040 MipsOperand *getMemBase() const {
1041 assert((Kind == k_Memory) && "Invalid access!");
1045 const MCExpr *getMemOff() const {
1046 assert((Kind == k_Memory) && "Invalid access!");
1050 int64_t getConstantMemOff() const {
1051 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1054 const SmallVectorImpl<unsigned> &getRegList() const {
1055 assert((Kind == k_RegList) && "Invalid access!");
1056 return *(RegList.List);
1059 unsigned getRegPair() const {
1060 assert((Kind == k_RegPair) && "Invalid access!");
1061 return RegIdx.Index;
1064 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1065 MipsAsmParser &Parser) {
1066 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1067 Op->Tok.Data = Str.data();
1068 Op->Tok.Length = Str.size();
1074 /// Create a numeric register (e.g. $1). The exact register remains
1075 /// unresolved until an instruction successfully matches
1076 static std::unique_ptr<MipsOperand>
1077 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1078 SMLoc E, MipsAsmParser &Parser) {
1079 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1080 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1083 /// Create a register that is definitely a GPR.
1084 /// This is typically only used for named registers such as $gp.
1085 static std::unique_ptr<MipsOperand>
1086 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1087 MipsAsmParser &Parser) {
1088 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1091 /// Create a register that is definitely a FGR.
1092 /// This is typically only used for named registers such as $f0.
1093 static std::unique_ptr<MipsOperand>
1094 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1095 MipsAsmParser &Parser) {
1096 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1099 /// Create a register that is definitely a HWReg.
1100 /// This is typically only used for named registers such as $hwr_cpunum.
1101 static std::unique_ptr<MipsOperand>
1102 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1103 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1104 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1107 /// Create a register that is definitely an FCC.
1108 /// This is typically only used for named registers such as $fcc0.
1109 static std::unique_ptr<MipsOperand>
1110 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1111 MipsAsmParser &Parser) {
1112 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1115 /// Create a register that is definitely an ACC.
1116 /// This is typically only used for named registers such as $ac0.
1117 static std::unique_ptr<MipsOperand>
1118 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1119 MipsAsmParser &Parser) {
1120 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1123 /// Create a register that is definitely an MSA128.
1124 /// This is typically only used for named registers such as $w0.
1125 static std::unique_ptr<MipsOperand>
1126 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1127 SMLoc E, MipsAsmParser &Parser) {
1128 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1131 /// Create a register that is definitely an MSACtrl.
1132 /// This is typically only used for named registers such as $msaaccess.
1133 static std::unique_ptr<MipsOperand>
1134 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1135 SMLoc E, MipsAsmParser &Parser) {
1136 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1139 static std::unique_ptr<MipsOperand>
1140 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1141 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1148 static std::unique_ptr<MipsOperand>
1149 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1150 SMLoc E, MipsAsmParser &Parser) {
1151 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1152 Op->Mem.Base = Base.release();
1159 static std::unique_ptr<MipsOperand>
1160 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1161 MipsAsmParser &Parser) {
1162 assert (Regs.size() > 0 && "Empty list not allowed");
1164 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1165 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1166 Op->StartLoc = StartLoc;
1167 Op->EndLoc = EndLoc;
1171 static std::unique_ptr<MipsOperand>
1172 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1173 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1174 Op->RegIdx.Index = RegNo;
1180 bool isGPRAsmReg() const {
1181 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1183 bool isMM16AsmReg() const {
1184 if (!(isRegIdx() && RegIdx.Kind))
1186 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1187 || RegIdx.Index == 16 || RegIdx.Index == 17);
1189 bool isMM16AsmRegZero() const {
1190 if (!(isRegIdx() && RegIdx.Kind))
1192 return (RegIdx.Index == 0 ||
1193 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1194 RegIdx.Index == 17);
1196 bool isMM16AsmRegMoveP() const {
1197 if (!(isRegIdx() && RegIdx.Kind))
1199 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1200 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1202 bool isFGRAsmReg() const {
1203 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1204 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1206 bool isHWRegsAsmReg() const {
1207 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1209 bool isCCRAsmReg() const {
1210 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1212 bool isFCCAsmReg() const {
1213 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1215 if (!AsmParser.hasEightFccRegisters())
1216 return RegIdx.Index == 0;
1217 return RegIdx.Index <= 7;
1219 bool isACCAsmReg() const {
1220 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1222 bool isCOP0AsmReg() const {
1223 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1225 bool isCOP2AsmReg() const {
1226 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1228 bool isCOP3AsmReg() const {
1229 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1231 bool isMSA128AsmReg() const {
1232 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1234 bool isMSACtrlAsmReg() const {
1235 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1238 /// getStartLoc - Get the location of the first token of this operand.
1239 SMLoc getStartLoc() const override { return StartLoc; }
1240 /// getEndLoc - Get the location of the last token of this operand.
1241 SMLoc getEndLoc() const override { return EndLoc; }
1243 virtual ~MipsOperand() {
1251 delete RegList.List;
1252 case k_PhysRegister:
1253 case k_RegisterIndex:
1260 void print(raw_ostream &OS) const override {
1269 Mem.Base->print(OS);
1274 case k_PhysRegister:
1275 OS << "PhysReg<" << PhysReg.Num << ">";
1277 case k_RegisterIndex:
1278 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1285 for (auto Reg : (*RegList.List))
1290 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1294 }; // class MipsOperand
1298 extern const MCInstrDesc MipsInsts[];
1300 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1301 return MipsInsts[Opcode];
1304 static bool hasShortDelaySlot(unsigned Opcode) {
1307 case Mips::JALRS_MM:
1308 case Mips::JALRS16_MM:
1309 case Mips::BGEZALS_MM:
1310 case Mips::BLTZALS_MM:
1317 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1318 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1319 return &SRExpr->getSymbol();
1322 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1323 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1324 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1335 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1336 return getSingleMCSymbol(UExpr->getSubExpr());
1341 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1342 if (isa<MCSymbolRefExpr>(Expr))
1345 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1346 return countMCSymbolRefExpr(BExpr->getLHS()) +
1347 countMCSymbolRefExpr(BExpr->getRHS());
1349 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1350 return countMCSymbolRefExpr(UExpr->getSubExpr());
1355 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1356 SmallVectorImpl<MCInst> &Instructions) {
1357 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1361 if (MCID.isBranch() || MCID.isCall()) {
1362 const unsigned Opcode = Inst.getOpcode();
1372 assert(hasCnMips() && "instruction only valid for octeon cpus");
1379 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1380 Offset = Inst.getOperand(2);
1381 if (!Offset.isImm())
1382 break; // We'll deal with this situation later on when applying fixups.
1383 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1384 return Error(IDLoc, "branch target out of range");
1385 if (OffsetToAlignment(Offset.getImm(),
1386 1LL << (inMicroMipsMode() ? 1 : 2)))
1387 return Error(IDLoc, "branch to misaligned address");
1401 case Mips::BGEZAL_MM:
1402 case Mips::BLTZAL_MM:
1405 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1406 Offset = Inst.getOperand(1);
1407 if (!Offset.isImm())
1408 break; // We'll deal with this situation later on when applying fixups.
1409 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1410 return Error(IDLoc, "branch target out of range");
1411 if (OffsetToAlignment(Offset.getImm(),
1412 1LL << (inMicroMipsMode() ? 1 : 2)))
1413 return Error(IDLoc, "branch to misaligned address");
1415 case Mips::BEQZ16_MM:
1416 case Mips::BEQZC16_MMR6:
1417 case Mips::BNEZ16_MM:
1418 case Mips::BNEZC16_MMR6:
1419 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1420 Offset = Inst.getOperand(1);
1421 if (!Offset.isImm())
1422 break; // We'll deal with this situation later on when applying fixups.
1423 if (!isIntN(8, Offset.getImm()))
1424 return Error(IDLoc, "branch target out of range");
1425 if (OffsetToAlignment(Offset.getImm(), 2LL))
1426 return Error(IDLoc, "branch to misaligned address");
1431 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1432 // We still accept it but it is a normal nop.
1433 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1434 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1435 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1440 const unsigned Opcode = Inst.getOpcode();
1452 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1453 // The offset is handled above
1454 Opnd = Inst.getOperand(1);
1456 return Error(IDLoc, "expected immediate operand kind");
1457 Imm = Opnd.getImm();
1458 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1459 Opcode == Mips::BBIT1 ? 63 : 31))
1460 return Error(IDLoc, "immediate operand value out of range");
1462 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1464 Inst.getOperand(1).setImm(Imm - 32);
1472 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1474 Opnd = Inst.getOperand(3);
1476 return Error(IDLoc, "expected immediate operand kind");
1477 Imm = Opnd.getImm();
1478 if (Imm < 0 || Imm > 31)
1479 return Error(IDLoc, "immediate operand value out of range");
1481 Opnd = Inst.getOperand(2);
1483 return Error(IDLoc, "expected immediate operand kind");
1484 Imm = Opnd.getImm();
1485 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1486 Opcode == Mips::EXTS ? 63 : 31))
1487 return Error(IDLoc, "immediate operand value out of range");
1489 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1490 Inst.getOperand(2).setImm(Imm - 32);
1496 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1497 Opnd = Inst.getOperand(2);
1499 return Error(IDLoc, "expected immediate operand kind");
1500 Imm = Opnd.getImm();
1501 if (!isInt<10>(Imm))
1502 return Error(IDLoc, "immediate operand value out of range");
1507 // This expansion is not in a function called by expandInstruction() because
1508 // the pseudo-instruction doesn't have a distinct opcode.
1509 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1511 warnIfNoMacro(IDLoc);
1513 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1515 // We can do this expansion if there's only 1 symbol in the argument
1517 if (countMCSymbolRefExpr(JalExpr) > 1)
1518 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1520 // FIXME: This is checking the expression can be handled by the later stages
1521 // of the assembler. We ought to leave it to those later stages but
1522 // we can't do that until we stop evaluateRelocExpr() rewriting the
1523 // expressions into non-equivalent forms.
1524 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1526 // FIXME: Add support for label+offset operands (currently causes an error).
1527 // FIXME: Add support for forward-declared local symbols.
1528 // FIXME: Add expansion for when the LargeGOT option is enabled.
1529 if (JalSym->isInSection() || JalSym->isTemporary()) {
1531 // If it's a local symbol and the O32 ABI is being used, we expand to:
1533 // R_(MICRO)MIPS_GOT16 label
1534 // addiu $25, $25, 0
1535 // R_(MICRO)MIPS_LO16 label
1537 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1538 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1541 LwInst.setOpcode(Mips::LW);
1542 LwInst.addOperand(MCOperand::createReg(Mips::T9));
1543 LwInst.addOperand(MCOperand::createReg(Mips::GP));
1544 LwInst.addOperand(MCOperand::createExpr(Got16RelocExpr));
1545 Instructions.push_back(LwInst);
1548 AddiuInst.setOpcode(Mips::ADDiu);
1549 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1550 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1551 AddiuInst.addOperand(MCOperand::createExpr(Lo16RelocExpr));
1552 Instructions.push_back(AddiuInst);
1553 } else if (isABI_N32() || isABI_N64()) {
1554 // If it's a local symbol and the N32/N64 ABIs are being used,
1556 // lw/ld $25, 0($gp)
1557 // R_(MICRO)MIPS_GOT_DISP label
1559 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1562 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1563 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1564 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1565 LoadInst.addOperand(MCOperand::createExpr(GotDispRelocExpr));
1566 Instructions.push_back(LoadInst);
1569 // If it's an external/weak symbol, we expand to:
1570 // lw/ld $25, 0($gp)
1571 // R_(MICRO)MIPS_CALL16 label
1573 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1576 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1577 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1578 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1579 LoadInst.addOperand(MCOperand::createExpr(Call16RelocExpr));
1580 Instructions.push_back(LoadInst);
1584 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1585 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1586 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1588 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1589 // This relocation is supposed to be an optimization hint for the linker
1590 // and is not necessary for correctness.
1595 if (MCID.mayLoad() || MCID.mayStore()) {
1596 // Check the offset of memory operand, if it is a symbol
1597 // reference or immediate we may have to expand instructions.
1598 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1599 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1600 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1601 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1602 MCOperand &Op = Inst.getOperand(i);
1604 int MemOffset = Op.getImm();
1605 if (MemOffset < -32768 || MemOffset > 32767) {
1606 // Offset can't exceed 16bit value.
1607 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1610 } else if (Op.isExpr()) {
1611 const MCExpr *Expr = Op.getExpr();
1612 if (Expr->getKind() == MCExpr::SymbolRef) {
1613 const MCSymbolRefExpr *SR =
1614 static_cast<const MCSymbolRefExpr *>(Expr);
1615 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1617 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1620 } else if (!isEvaluated(Expr)) {
1621 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1629 if (inMicroMipsMode()) {
1630 if (MCID.mayLoad()) {
1631 // Try to create 16-bit GP relative load instruction.
1632 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1633 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1634 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1635 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1636 MCOperand &Op = Inst.getOperand(i);
1638 int MemOffset = Op.getImm();
1639 MCOperand &DstReg = Inst.getOperand(0);
1640 MCOperand &BaseReg = Inst.getOperand(1);
1641 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1642 getContext().getRegisterInfo()->getRegClass(
1643 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1644 (BaseReg.getReg() == Mips::GP ||
1645 BaseReg.getReg() == Mips::GP_64)) {
1647 TmpInst.setLoc(IDLoc);
1648 TmpInst.setOpcode(Mips::LWGP_MM);
1649 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1650 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1651 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1652 Instructions.push_back(TmpInst);
1660 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1665 switch (Inst.getOpcode()) {
1668 case Mips::ADDIUS5_MM:
1669 Opnd = Inst.getOperand(2);
1671 return Error(IDLoc, "expected immediate operand kind");
1672 Imm = Opnd.getImm();
1673 if (Imm < -8 || Imm > 7)
1674 return Error(IDLoc, "immediate operand value out of range");
1676 case Mips::ADDIUSP_MM:
1677 Opnd = Inst.getOperand(0);
1679 return Error(IDLoc, "expected immediate operand kind");
1680 Imm = Opnd.getImm();
1681 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1683 return Error(IDLoc, "immediate operand value out of range");
1685 case Mips::SLL16_MM:
1686 case Mips::SRL16_MM:
1687 Opnd = Inst.getOperand(2);
1689 return Error(IDLoc, "expected immediate operand kind");
1690 Imm = Opnd.getImm();
1691 if (Imm < 1 || Imm > 8)
1692 return Error(IDLoc, "immediate operand value out of range");
1695 Opnd = Inst.getOperand(1);
1697 return Error(IDLoc, "expected immediate operand kind");
1698 Imm = Opnd.getImm();
1699 if (Imm < -1 || Imm > 126)
1700 return Error(IDLoc, "immediate operand value out of range");
1702 case Mips::ADDIUR2_MM:
1703 Opnd = Inst.getOperand(2);
1705 return Error(IDLoc, "expected immediate operand kind");
1706 Imm = Opnd.getImm();
1707 if (!(Imm == 1 || Imm == -1 ||
1708 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1709 return Error(IDLoc, "immediate operand value out of range");
1711 case Mips::ADDIUR1SP_MM:
1712 Opnd = Inst.getOperand(1);
1714 return Error(IDLoc, "expected immediate operand kind");
1715 Imm = Opnd.getImm();
1716 if (OffsetToAlignment(Imm, 4LL))
1717 return Error(IDLoc, "misaligned immediate operand value");
1718 if (Imm < 0 || Imm > 255)
1719 return Error(IDLoc, "immediate operand value out of range");
1721 case Mips::ANDI16_MM:
1722 Opnd = Inst.getOperand(2);
1724 return Error(IDLoc, "expected immediate operand kind");
1725 Imm = Opnd.getImm();
1726 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1727 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1728 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1729 return Error(IDLoc, "immediate operand value out of range");
1731 case Mips::LBU16_MM:
1732 Opnd = Inst.getOperand(2);
1734 return Error(IDLoc, "expected immediate operand kind");
1735 Imm = Opnd.getImm();
1736 if (Imm < -1 || Imm > 14)
1737 return Error(IDLoc, "immediate operand value out of range");
1746 Opnd = Inst.getOperand(2);
1748 return Error(IDLoc, "expected immediate operand kind");
1749 Imm = Opnd.getImm();
1750 if (Imm < 0 || Imm > 15)
1751 return Error(IDLoc, "immediate operand value out of range");
1753 case Mips::LHU16_MM:
1755 Opnd = Inst.getOperand(2);
1757 return Error(IDLoc, "expected immediate operand kind");
1758 Imm = Opnd.getImm();
1759 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1760 return Error(IDLoc, "immediate operand value out of range");
1764 Opnd = Inst.getOperand(2);
1766 return Error(IDLoc, "expected immediate operand kind");
1767 Imm = Opnd.getImm();
1768 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1769 return Error(IDLoc, "immediate operand value out of range");
1771 case Mips::PREFX_MM:
1774 Opnd = Inst.getOperand(2);
1776 return Error(IDLoc, "expected immediate operand kind");
1777 Imm = Opnd.getImm();
1778 if (!isUInt<5>(Imm))
1779 return Error(IDLoc, "immediate operand value out of range");
1781 case Mips::ADDIUPC_MM:
1782 MCOperand Opnd = Inst.getOperand(1);
1784 return Error(IDLoc, "expected immediate operand kind");
1785 int Imm = Opnd.getImm();
1786 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1787 return Error(IDLoc, "immediate operand value out of range");
1792 if (needsExpansion(Inst)) {
1793 if (expandInstruction(Inst, IDLoc, Instructions))
1796 Instructions.push_back(Inst);
1798 // If this instruction has a delay slot and .set reorder is active,
1799 // emit a NOP after it.
1800 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1801 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1806 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1808 switch (Inst.getOpcode()) {
1809 case Mips::LoadImm32:
1810 case Mips::LoadImm64:
1811 case Mips::LoadAddrImm32:
1812 case Mips::LoadAddrImm64:
1813 case Mips::LoadAddrReg32:
1814 case Mips::LoadAddrReg64:
1815 case Mips::B_MM_Pseudo:
1816 case Mips::B_MMR6_Pseudo:
1819 case Mips::JalOneReg:
1820 case Mips::JalTwoReg:
1839 case Mips::SDivMacro:
1840 case Mips::UDivMacro:
1841 case Mips::DSDivMacro:
1842 case Mips::DUDivMacro:
1851 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1852 SmallVectorImpl<MCInst> &Instructions) {
1853 switch (Inst.getOpcode()) {
1854 default: llvm_unreachable("unimplemented expansion");
1855 case Mips::LoadImm32:
1856 return expandLoadImm(Inst, true, IDLoc, Instructions);
1857 case Mips::LoadImm64:
1858 return expandLoadImm(Inst, false, IDLoc, Instructions);
1859 case Mips::LoadAddrImm32:
1860 case Mips::LoadAddrImm64:
1861 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1862 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1863 "expected immediate operand kind");
1865 return expandLoadAddress(
1866 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1867 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1868 case Mips::LoadAddrReg32:
1869 case Mips::LoadAddrReg64:
1870 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1871 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1872 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1873 "expected immediate operand kind");
1875 return expandLoadAddress(
1876 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1877 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1878 case Mips::B_MM_Pseudo:
1879 case Mips::B_MMR6_Pseudo:
1880 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1883 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1884 case Mips::JalOneReg:
1885 case Mips::JalTwoReg:
1886 return expandJalWithRegs(Inst, IDLoc, Instructions);
1889 return expandBranchImm(Inst, IDLoc, Instructions);
1906 return expandCondBranches(Inst, IDLoc, Instructions);
1907 case Mips::SDivMacro:
1908 return expandDiv(Inst, IDLoc, Instructions, false, true);
1909 case Mips::DSDivMacro:
1910 return expandDiv(Inst, IDLoc, Instructions, true, true);
1911 case Mips::UDivMacro:
1912 return expandDiv(Inst, IDLoc, Instructions, false, false);
1913 case Mips::DUDivMacro:
1914 return expandDiv(Inst, IDLoc, Instructions, true, false);
1916 return expandUlhu(Inst, IDLoc, Instructions);
1918 return expandUlw(Inst, IDLoc, Instructions);
1923 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1924 SmallVectorImpl<MCInst> &Instructions) {
1926 tmpInst.setOpcode(Opcode);
1927 tmpInst.addOperand(MCOperand::createReg(Reg0));
1928 tmpInst.addOperand(Op1);
1929 tmpInst.setLoc(IDLoc);
1930 Instructions.push_back(tmpInst);
1933 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1934 SmallVectorImpl<MCInst> &Instructions) {
1935 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1938 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1939 SmallVectorImpl<MCInst> &Instructions) {
1940 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1943 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1944 SmallVectorImpl<MCInst> &Instructions) {
1946 tmpInst.setOpcode(Opcode);
1947 tmpInst.addOperand(MCOperand::createImm(Imm1));
1948 tmpInst.addOperand(MCOperand::createImm(Imm2));
1949 tmpInst.setLoc(IDLoc);
1950 Instructions.push_back(tmpInst);
1953 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1954 SmallVectorImpl<MCInst> &Instructions) {
1956 tmpInst.setOpcode(Opcode);
1957 tmpInst.addOperand(MCOperand::createReg(Reg0));
1958 tmpInst.setLoc(IDLoc);
1959 Instructions.push_back(tmpInst);
1962 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1963 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1965 tmpInst.setOpcode(Opcode);
1966 tmpInst.addOperand(MCOperand::createReg(Reg0));
1967 tmpInst.addOperand(MCOperand::createReg(Reg1));
1968 tmpInst.addOperand(Op2);
1969 tmpInst.setLoc(IDLoc);
1970 Instructions.push_back(tmpInst);
1973 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1974 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1975 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1979 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1980 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1981 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1985 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1986 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1987 if (ShiftAmount >= 32) {
1988 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1993 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1995 } // end anonymous namespace.
1997 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1998 SmallVectorImpl<MCInst> &Instructions) {
1999 // Create a JALR instruction which is going to replace the pseudo-JAL.
2001 JalrInst.setLoc(IDLoc);
2002 const MCOperand FirstRegOp = Inst.getOperand(0);
2003 const unsigned Opcode = Inst.getOpcode();
2005 if (Opcode == Mips::JalOneReg) {
2006 // jal $rs => jalr $rs
2007 if (inMicroMipsMode()) {
2008 JalrInst.setOpcode(Mips::JALR16_MM);
2009 JalrInst.addOperand(FirstRegOp);
2011 JalrInst.setOpcode(Mips::JALR);
2012 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2013 JalrInst.addOperand(FirstRegOp);
2015 } else if (Opcode == Mips::JalTwoReg) {
2016 // jal $rd, $rs => jalr $rd, $rs
2017 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2018 JalrInst.addOperand(FirstRegOp);
2019 const MCOperand SecondRegOp = Inst.getOperand(1);
2020 JalrInst.addOperand(SecondRegOp);
2022 Instructions.push_back(JalrInst);
2024 // If .set reorder is active, emit a NOP after it.
2025 if (AssemblerOptions.back()->isReorder()) {
2026 // This is a 32-bit NOP because these 2 pseudo-instructions
2027 // do not have a short delay slot.
2029 NopInst.setOpcode(Mips::SLL);
2030 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2031 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2032 NopInst.addOperand(MCOperand::createImm(0));
2033 Instructions.push_back(NopInst);
2039 /// Can the value be represented by a unsigned N-bit value and a shift left?
2040 template<unsigned N>
2041 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2042 unsigned BitNum = findFirstSet(x);
2044 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2047 /// Load (or add) an immediate into a register.
2049 /// @param ImmValue The immediate to load.
2050 /// @param DstReg The register that will hold the immediate.
2051 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2052 /// for a simple initialization.
2053 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2054 /// @param IsAddress True if the immediate represents an address. False if it
2056 /// @param IDLoc Location of the immediate in the source file.
2057 /// @param Instructions The instructions emitted by this expansion.
2058 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2059 unsigned SrcReg, bool Is32BitImm,
2060 bool IsAddress, SMLoc IDLoc,
2061 SmallVectorImpl<MCInst> &Instructions) {
2062 if (!Is32BitImm && !isGP64bit()) {
2063 Error(IDLoc, "instruction requires a 64-bit architecture");
2068 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2069 // Sign extend up to 64-bit so that the predicates match the hardware
2070 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2072 ImmValue = SignExtend64<32>(ImmValue);
2074 Error(IDLoc, "instruction requires a 32-bit immediate");
2079 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2080 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2082 bool UseSrcReg = false;
2083 if (SrcReg != Mips::NoRegister)
2086 unsigned TmpReg = DstReg;
2087 if (UseSrcReg && (DstReg == SrcReg)) {
2088 // At this point we need AT to perform the expansions and we exit if it is
2090 unsigned ATReg = getATReg(IDLoc);
2096 if (isInt<16>(ImmValue)) {
2100 // This doesn't quite follow the usual ABI expectations for N32 but matches
2101 // traditional assembler behaviour. N32 would normally use addiu for both
2102 // integers and addresses.
2103 if (IsAddress && !Is32BitImm) {
2104 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2108 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2112 if (isUInt<16>(ImmValue)) {
2113 unsigned TmpReg = DstReg;
2114 if (SrcReg == DstReg) {
2115 TmpReg = getATReg(IDLoc);
2120 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2122 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2126 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2127 warnIfNoMacro(IDLoc);
2129 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2130 uint16_t Bits15To0 = ImmValue & 0xffff;
2132 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2133 // Traditional behaviour seems to special case this particular value. It's
2134 // not clear why other masks are handled differently.
2135 if (ImmValue == 0xffffffff) {
2136 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2137 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2139 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2143 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2145 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2146 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2148 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2150 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2154 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2156 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2158 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2162 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2164 Error(IDLoc, "instruction requires a 32-bit immediate");
2168 // Traditionally, these immediates are shifted as little as possible and as
2169 // such we align the most significant bit to bit 15 of our temporary.
2170 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2171 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2172 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2173 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2174 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2175 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2178 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2183 warnIfNoMacro(IDLoc);
2185 // The remaining case is packed with a sequence of dsll and ori with zeros
2186 // being omitted and any neighbouring dsll's being coalesced.
2187 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2189 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2190 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2191 IDLoc, Instructions))
2194 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2195 // skip it and defer the shift to the next chunk.
2196 unsigned ShiftCarriedForwards = 16;
2197 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2198 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2200 if (ImmChunk != 0) {
2201 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2203 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2204 ShiftCarriedForwards = 0;
2207 ShiftCarriedForwards += 16;
2209 ShiftCarriedForwards -= 16;
2211 // Finish any remaining shifts left by trailing zeros.
2212 if (ShiftCarriedForwards)
2213 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2217 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2222 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2223 SmallVectorImpl<MCInst> &Instructions) {
2224 const MCOperand &ImmOp = Inst.getOperand(1);
2225 assert(ImmOp.isImm() && "expected immediate operand kind");
2226 const MCOperand &DstRegOp = Inst.getOperand(0);
2227 assert(DstRegOp.isReg() && "expected register operand kind");
2229 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2230 Is32BitImm, false, IDLoc, Instructions))
2236 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2237 const MCOperand &Offset,
2238 bool Is32BitAddress, SMLoc IDLoc,
2239 SmallVectorImpl<MCInst> &Instructions) {
2240 // la can't produce a usable address when addresses are 64-bit.
2241 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2242 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2243 // We currently can't do this because we depend on the equality
2244 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2245 Error(IDLoc, "la used to load 64-bit address");
2246 // Continue as if we had 'dla' instead.
2247 Is32BitAddress = false;
2250 // dla requires 64-bit addresses.
2251 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2252 Error(IDLoc, "instruction requires a 64-bit architecture");
2256 if (!Offset.isImm())
2257 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2258 Is32BitAddress, IDLoc, Instructions);
2260 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2261 IDLoc, Instructions);
2264 bool MipsAsmParser::loadAndAddSymbolAddress(
2265 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2266 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2267 warnIfNoMacro(IDLoc);
2269 // FIXME: The way we're handling symbols right now prevents simple expressions
2270 // like foo+8. We'll be able to fix this once our unary operators (%hi
2271 // and similar) are treated as operators rather than as fixup types.
2272 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2273 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2274 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2275 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2276 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2278 bool UseSrcReg = SrcReg != Mips::NoRegister;
2280 // This is the 64-bit symbol address expansion.
2281 if (ABI.ArePtrs64bit() && isGP64bit()) {
2282 // We always need AT for the 64-bit expansion.
2283 // If it is not available we exit.
2284 unsigned ATReg = getATReg(IDLoc);
2288 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2289 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2290 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2291 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2293 if (UseSrcReg && (DstReg == SrcReg)) {
2294 // If $rs is the same as $rd:
2295 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2296 // daddiu $at, $at, %higher(sym)
2297 // dsll $at, $at, 16
2298 // daddiu $at, $at, %hi(sym)
2299 // dsll $at, $at, 16
2300 // daddiu $at, $at, %lo(sym)
2301 // daddu $rd, $at, $rd
2302 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2304 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2305 IDLoc, Instructions);
2306 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2307 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2309 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2310 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2312 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2317 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2318 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2319 // lui $at, %hi(sym)
2320 // daddiu $rd, $rd, %higher(sym)
2321 // daddiu $at, $at, %lo(sym)
2322 // dsll32 $rd, $rd, 0
2323 // daddu $rd, $rd, $at
2324 // (daddu $rd, $rd, $rs)
2325 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2327 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2329 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2330 IDLoc, Instructions);
2331 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2333 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2334 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2336 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2341 // And now, the 32-bit symbol address expansion:
2342 // If $rs is the same as $rd:
2343 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2344 // ori $at, $at, %lo(sym)
2345 // addu $rd, $at, $rd
2346 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2347 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2348 // ori $rd, $rd, %lo(sym)
2349 // (addu $rd, $rd, $rs)
2350 unsigned TmpReg = DstReg;
2351 if (UseSrcReg && (DstReg == SrcReg)) {
2352 // If $rs is the same as $rd, we need to use AT.
2353 // If it is not available we exit.
2354 unsigned ATReg = getATReg(IDLoc);
2360 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2361 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2365 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2367 assert(DstReg == TmpReg);
2372 bool MipsAsmParser::expandUncondBranchMMPseudo(
2373 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2374 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2375 "unexpected number of operands");
2377 MCOperand Offset = Inst.getOperand(0);
2378 if (Offset.isExpr()) {
2380 Inst.setOpcode(Mips::BEQ_MM);
2381 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2382 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2383 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2385 assert(Offset.isImm() && "expected immediate operand kind");
2386 if (isIntN(11, Offset.getImm())) {
2387 // If offset fits into 11 bits then this instruction becomes microMIPS
2388 // 16-bit unconditional branch instruction.
2389 if (inMicroMipsMode())
2390 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2392 if (!isIntN(17, Offset.getImm()))
2393 Error(IDLoc, "branch target out of range");
2394 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2395 Error(IDLoc, "branch to misaligned address");
2397 Inst.setOpcode(Mips::BEQ_MM);
2398 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2399 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2400 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2403 Instructions.push_back(Inst);
2405 // If .set reorder is active and branch instruction has a delay slot,
2406 // emit a NOP after it.
2407 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2408 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2409 createNop(true, IDLoc, Instructions);
2414 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2415 SmallVectorImpl<MCInst> &Instructions) {
2416 const MCOperand &DstRegOp = Inst.getOperand(0);
2417 assert(DstRegOp.isReg() && "expected register operand kind");
2419 const MCOperand &ImmOp = Inst.getOperand(1);
2420 assert(ImmOp.isImm() && "expected immediate operand kind");
2422 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2423 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2425 unsigned OpCode = 0;
2426 switch(Inst.getOpcode()) {
2434 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2438 int64_t ImmValue = ImmOp.getImm();
2439 if (ImmValue == 0) {
2441 BranchInst.setOpcode(OpCode);
2442 BranchInst.addOperand(DstRegOp);
2443 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2444 BranchInst.addOperand(MemOffsetOp);
2445 Instructions.push_back(BranchInst);
2447 warnIfNoMacro(IDLoc);
2449 unsigned ATReg = getATReg(IDLoc);
2453 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2454 IDLoc, Instructions))
2458 BranchInst.setOpcode(OpCode);
2459 BranchInst.addOperand(DstRegOp);
2460 BranchInst.addOperand(MCOperand::createReg(ATReg));
2461 BranchInst.addOperand(MemOffsetOp);
2462 Instructions.push_back(BranchInst);
2467 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2468 SmallVectorImpl<MCInst> &Instructions,
2469 bool isLoad, bool isImmOpnd) {
2471 unsigned ImmOffset, HiOffset, LoOffset;
2472 const MCExpr *ExprOffset;
2474 // 1st operand is either the source or destination register.
2475 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2476 unsigned RegOpNum = Inst.getOperand(0).getReg();
2477 // 2nd operand is the base register.
2478 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2479 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2480 // 3rd operand is either an immediate or expression.
2482 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2483 ImmOffset = Inst.getOperand(2).getImm();
2484 LoOffset = ImmOffset & 0x0000ffff;
2485 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2486 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2487 if (LoOffset & 0x8000)
2490 ExprOffset = Inst.getOperand(2).getExpr();
2491 // All instructions will have the same location.
2492 TempInst.setLoc(IDLoc);
2493 // These are some of the types of expansions we perform here:
2494 // 1) lw $8, sym => lui $8, %hi(sym)
2495 // lw $8, %lo(sym)($8)
2496 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2498 // lw $8, %lo(offset)($9)
2499 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2501 // lw $8, %lo(offset)($at)
2502 // 4) sw $8, sym => lui $at, %hi(sym)
2503 // sw $8, %lo(sym)($at)
2504 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2506 // sw $8, %lo(offset)($at)
2507 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2508 // ldc1 $f0, %lo(sym)($at)
2510 // For load instructions we can use the destination register as a temporary
2511 // if base and dst are different (examples 1 and 2) and if the base register
2512 // is general purpose otherwise we must use $at (example 6) and error if it's
2513 // not available. For stores we must use $at (examples 4 and 5) because we
2514 // must not clobber the source register setting up the offset.
2515 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2516 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2517 unsigned RegClassIDOp0 =
2518 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2519 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2520 (RegClassIDOp0 == Mips::GPR64RegClassID);
2521 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2522 TmpRegNum = RegOpNum;
2524 // At this point we need AT to perform the expansions and we exit if it is
2526 TmpRegNum = getATReg(IDLoc);
2531 TempInst.setOpcode(Mips::LUi);
2532 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2534 TempInst.addOperand(MCOperand::createImm(HiOffset));
2536 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2537 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2539 // Add the instruction to the list.
2540 Instructions.push_back(TempInst);
2541 // Prepare TempInst for next instruction.
2543 // Add temp register to base.
2544 if (BaseRegNum != Mips::ZERO) {
2545 TempInst.setOpcode(Mips::ADDu);
2546 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2547 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2548 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2549 Instructions.push_back(TempInst);
2552 // And finally, create original instruction with low part
2553 // of offset and new base.
2554 TempInst.setOpcode(Inst.getOpcode());
2555 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2556 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2558 TempInst.addOperand(MCOperand::createImm(LoOffset));
2560 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2561 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2563 Instructions.push_back(TempInst);
2568 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2569 SmallVectorImpl<MCInst> &Instructions) {
2570 unsigned OpNum = Inst.getNumOperands();
2571 unsigned Opcode = Inst.getOpcode();
2572 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2574 assert (Inst.getOperand(OpNum - 1).isImm() &&
2575 Inst.getOperand(OpNum - 2).isReg() &&
2576 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2578 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2579 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2580 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2581 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2582 // It can be implemented as SWM16 or LWM16 instruction.
2583 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2585 Inst.setOpcode(NewOpcode);
2586 Instructions.push_back(Inst);
2590 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2591 SmallVectorImpl<MCInst> &Instructions) {
2592 unsigned PseudoOpcode = Inst.getOpcode();
2593 unsigned SrcReg = Inst.getOperand(0).getReg();
2594 unsigned TrgReg = Inst.getOperand(1).getReg();
2595 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2597 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2598 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2600 switch (PseudoOpcode) {
2605 AcceptsEquality = false;
2606 ReverseOrderSLT = false;
2607 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2608 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2609 ZeroSrcOpcode = Mips::BGTZ;
2610 ZeroTrgOpcode = Mips::BLTZ;
2616 AcceptsEquality = true;
2617 ReverseOrderSLT = true;
2618 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2619 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2620 ZeroSrcOpcode = Mips::BGEZ;
2621 ZeroTrgOpcode = Mips::BLEZ;
2627 AcceptsEquality = true;
2628 ReverseOrderSLT = false;
2629 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2630 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2631 ZeroSrcOpcode = Mips::BLEZ;
2632 ZeroTrgOpcode = Mips::BGEZ;
2638 AcceptsEquality = false;
2639 ReverseOrderSLT = true;
2640 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2641 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2642 ZeroSrcOpcode = Mips::BLTZ;
2643 ZeroTrgOpcode = Mips::BGTZ;
2646 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2650 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2651 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2652 if (IsSrcRegZero && IsTrgRegZero) {
2653 // FIXME: All of these Opcode-specific if's are needed for compatibility
2654 // with GAS' behaviour. However, they may not generate the most efficient
2655 // code in some circumstances.
2656 if (PseudoOpcode == Mips::BLT) {
2657 BranchInst.setOpcode(Mips::BLTZ);
2658 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2659 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2660 Instructions.push_back(BranchInst);
2663 if (PseudoOpcode == Mips::BLE) {
2664 BranchInst.setOpcode(Mips::BLEZ);
2665 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2666 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2667 Instructions.push_back(BranchInst);
2668 Warning(IDLoc, "branch is always taken");
2671 if (PseudoOpcode == Mips::BGE) {
2672 BranchInst.setOpcode(Mips::BGEZ);
2673 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2674 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2675 Instructions.push_back(BranchInst);
2676 Warning(IDLoc, "branch is always taken");
2679 if (PseudoOpcode == Mips::BGT) {
2680 BranchInst.setOpcode(Mips::BGTZ);
2681 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2682 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2683 Instructions.push_back(BranchInst);
2686 if (PseudoOpcode == Mips::BGTU) {
2687 BranchInst.setOpcode(Mips::BNE);
2688 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2689 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2690 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2691 Instructions.push_back(BranchInst);
2694 if (AcceptsEquality) {
2695 // If both registers are $0 and the pseudo-branch accepts equality, it
2696 // will always be taken, so we emit an unconditional branch.
2697 BranchInst.setOpcode(Mips::BEQ);
2698 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2699 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2700 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2701 Instructions.push_back(BranchInst);
2702 Warning(IDLoc, "branch is always taken");
2705 // If both registers are $0 and the pseudo-branch does not accept
2706 // equality, it will never be taken, so we don't have to emit anything.
2709 if (IsSrcRegZero || IsTrgRegZero) {
2710 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2711 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2712 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2713 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2714 // the pseudo-branch will never be taken, so we don't emit anything.
2715 // This only applies to unsigned pseudo-branches.
2718 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2719 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2720 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2721 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2722 // the pseudo-branch will always be taken, so we emit an unconditional
2724 // This only applies to unsigned pseudo-branches.
2725 BranchInst.setOpcode(Mips::BEQ);
2726 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2727 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2728 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2729 Instructions.push_back(BranchInst);
2730 Warning(IDLoc, "branch is always taken");
2734 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2735 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2736 // the pseudo-branch will be taken only when the non-zero register is
2737 // different from 0, so we emit a BNEZ.
2739 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2740 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2741 // the pseudo-branch will be taken only when the non-zero register is
2742 // equal to 0, so we emit a BEQZ.
2744 // Because only BLEU and BGEU branch on equality, we can use the
2745 // AcceptsEquality variable to decide when to emit the BEQZ.
2746 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2747 BranchInst.addOperand(
2748 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2749 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2750 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2751 Instructions.push_back(BranchInst);
2754 // If we have a signed pseudo-branch and one of the registers is $0,
2755 // we can use an appropriate compare-to-zero branch. We select which one
2756 // to use in the switch statement above.
2757 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2758 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2759 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2760 Instructions.push_back(BranchInst);
2764 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2765 // expansions. If it is not available, we return.
2766 unsigned ATRegNum = getATReg(IDLoc);
2770 warnIfNoMacro(IDLoc);
2772 // SLT fits well with 2 of our 4 pseudo-branches:
2773 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2774 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2775 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2776 // This is accomplished by using a BNEZ with the result of the SLT.
2778 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2779 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2780 // Because only BGE and BLE branch on equality, we can use the
2781 // AcceptsEquality variable to decide when to emit the BEQZ.
2782 // Note that the order of the SLT arguments doesn't change between
2785 // The same applies to the unsigned variants, except that SLTu is used
2788 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2789 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2790 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2791 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2792 Instructions.push_back(SetInst);
2795 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2797 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQL : Mips::BNEL);
2798 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2799 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2800 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2801 Instructions.push_back(BranchInst);
2805 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2806 SmallVectorImpl<MCInst> &Instructions,
2807 const bool IsMips64, const bool Signed) {
2808 if (hasMips32r6()) {
2809 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2813 warnIfNoMacro(IDLoc);
2815 const MCOperand &RsRegOp = Inst.getOperand(0);
2816 assert(RsRegOp.isReg() && "expected register operand kind");
2817 unsigned RsReg = RsRegOp.getReg();
2819 const MCOperand &RtRegOp = Inst.getOperand(1);
2820 assert(RtRegOp.isReg() && "expected register operand kind");
2821 unsigned RtReg = RtRegOp.getReg();
2826 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2827 ZeroReg = Mips::ZERO_64;
2829 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2830 ZeroReg = Mips::ZERO;
2833 bool UseTraps = useTraps();
2835 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2836 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2837 Warning(IDLoc, "dividing zero by zero");
2839 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2841 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2845 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2849 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2854 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2855 Warning(IDLoc, "division by zero");
2858 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2862 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2867 // FIXME: The values for these two BranchTarget variables may be different in
2868 // micromips. These magic numbers need to be removed.
2869 unsigned BranchTargetNoTraps;
2870 unsigned BranchTarget;
2873 BranchTarget = IsMips64 ? 12 : 8;
2874 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2876 BranchTarget = IsMips64 ? 20 : 16;
2877 BranchTargetNoTraps = 8;
2878 // Branch to the li instruction.
2879 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2883 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2886 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2889 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2893 unsigned ATReg = getATReg(IDLoc);
2897 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2899 // Branch to the mflo instruction.
2900 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2901 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2902 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2904 // Branch to the mflo instruction.
2905 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2906 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2910 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2912 // Branch to the mflo instruction.
2913 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2914 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2915 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2917 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2921 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2922 SmallVectorImpl<MCInst> &Instructions) {
2923 if (hasMips32r6() || hasMips64r6()) {
2924 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2928 warnIfNoMacro(IDLoc);
2930 const MCOperand &DstRegOp = Inst.getOperand(0);
2931 assert(DstRegOp.isReg() && "expected register operand kind");
2933 const MCOperand &SrcRegOp = Inst.getOperand(1);
2934 assert(SrcRegOp.isReg() && "expected register operand kind");
2936 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2937 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2939 unsigned DstReg = DstRegOp.getReg();
2940 unsigned SrcReg = SrcRegOp.getReg();
2941 int64_t OffsetValue = OffsetImmOp.getImm();
2943 // NOTE: We always need AT for ULHU, as it is always used as the source
2944 // register for one of the LBu's.
2945 unsigned ATReg = getATReg(IDLoc);
2949 // When the value of offset+1 does not fit in 16 bits, we have to load the
2950 // offset in AT, (D)ADDu the original source register (if there was one), and
2951 // then use AT as the source register for the 2 generated LBu's.
2952 bool LoadedOffsetInAT = false;
2953 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2954 LoadedOffsetInAT = true;
2956 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2957 true, IDLoc, Instructions))
2960 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2961 // because it will make our output more similar to GAS'. For example,
2962 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2963 // instead of just an "ori $1, $9, 32768".
2964 // NOTE: If there is no source register specified in the ULHU, the parser
2965 // will interpret it as $0.
2966 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2967 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2970 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2971 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2972 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2974 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2976 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2977 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2979 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2980 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2983 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2986 TmpInst.setOpcode(Mips::LBu);
2987 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2988 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2989 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2990 Instructions.push_back(TmpInst);
2993 TmpInst.setOpcode(Mips::LBu);
2994 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2995 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2996 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2997 Instructions.push_back(TmpInst);
3000 TmpInst.setOpcode(Mips::SLL);
3001 TmpInst.addOperand(MCOperand::createReg(SllReg));
3002 TmpInst.addOperand(MCOperand::createReg(SllReg));
3003 TmpInst.addOperand(MCOperand::createImm(8));
3004 Instructions.push_back(TmpInst);
3007 TmpInst.setOpcode(Mips::OR);
3008 TmpInst.addOperand(MCOperand::createReg(DstReg));
3009 TmpInst.addOperand(MCOperand::createReg(DstReg));
3010 TmpInst.addOperand(MCOperand::createReg(ATReg));
3011 Instructions.push_back(TmpInst);
3016 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3017 SmallVectorImpl<MCInst> &Instructions) {
3018 if (hasMips32r6() || hasMips64r6()) {
3019 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3023 const MCOperand &DstRegOp = Inst.getOperand(0);
3024 assert(DstRegOp.isReg() && "expected register operand kind");
3026 const MCOperand &SrcRegOp = Inst.getOperand(1);
3027 assert(SrcRegOp.isReg() && "expected register operand kind");
3029 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3030 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3032 unsigned SrcReg = SrcRegOp.getReg();
3033 int64_t OffsetValue = OffsetImmOp.getImm();
3036 // When the value of offset+3 does not fit in 16 bits, we have to load the
3037 // offset in AT, (D)ADDu the original source register (if there was one), and
3038 // then use AT as the source register for the generated LWL and LWR.
3039 bool LoadedOffsetInAT = false;
3040 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3041 ATReg = getATReg(IDLoc);
3044 LoadedOffsetInAT = true;
3046 warnIfNoMacro(IDLoc);
3048 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3049 true, IDLoc, Instructions))
3052 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3053 // because it will make our output more similar to GAS'. For example,
3054 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3055 // instead of just an "ori $1, $9, 32768".
3056 // NOTE: If there is no source register specified in the ULW, the parser
3057 // will interpret it as $0.
3058 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3059 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3062 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3063 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3065 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3066 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3068 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3069 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3072 MCInst LeftLoadInst;
3073 LeftLoadInst.setOpcode(Mips::LWL);
3074 LeftLoadInst.addOperand(DstRegOp);
3075 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3076 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3077 Instructions.push_back(LeftLoadInst);
3079 MCInst RightLoadInst;
3080 RightLoadInst.setOpcode(Mips::LWR);
3081 RightLoadInst.addOperand(DstRegOp);
3082 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3083 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3084 Instructions.push_back(RightLoadInst);
3089 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3090 SmallVectorImpl<MCInst> &Instructions) {
3092 if (hasShortDelaySlot) {
3093 NopInst.setOpcode(Mips::MOVE16_MM);
3094 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3095 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3097 NopInst.setOpcode(Mips::SLL);
3098 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3099 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3100 NopInst.addOperand(MCOperand::createImm(0));
3102 Instructions.push_back(NopInst);
3105 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3106 unsigned TrgReg, bool Is64Bit,
3107 SmallVectorImpl<MCInst> &Instructions) {
3108 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3112 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3113 // As described by the Mips32r2 spec, the registers Rd and Rs for
3114 // jalr.hb must be different.
3115 unsigned Opcode = Inst.getOpcode();
3117 if (Opcode == Mips::JALR_HB &&
3118 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3119 return Match_RequiresDifferentSrcAndDst;
3121 return Match_Success;
3124 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3125 OperandVector &Operands,
3127 uint64_t &ErrorInfo,
3128 bool MatchingInlineAsm) {
3131 SmallVector<MCInst, 8> Instructions;
3132 unsigned MatchResult =
3133 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3135 switch (MatchResult) {
3136 case Match_Success: {
3137 if (processInstruction(Inst, IDLoc, Instructions))
3139 for (unsigned i = 0; i < Instructions.size(); i++)
3140 Out.EmitInstruction(Instructions[i], STI);
3143 case Match_MissingFeature:
3144 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3146 case Match_InvalidOperand: {
3147 SMLoc ErrorLoc = IDLoc;
3148 if (ErrorInfo != ~0ULL) {
3149 if (ErrorInfo >= Operands.size())
3150 return Error(IDLoc, "too few operands for instruction");
3152 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3153 if (ErrorLoc == SMLoc())
3157 return Error(ErrorLoc, "invalid operand for instruction");
3159 case Match_MnemonicFail:
3160 return Error(IDLoc, "invalid instruction");
3161 case Match_RequiresDifferentSrcAndDst:
3162 return Error(IDLoc, "source and destination must be different");
3165 llvm_unreachable("Implement any new match types added!");
3168 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3169 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3170 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3171 ") without \".set noat\"");
3174 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3175 if (!AssemblerOptions.back()->isMacro())
3176 Warning(Loc, "macro instruction expanded into multiple instructions");
3180 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3181 SMRange Range, bool ShowColors) {
3182 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3183 Range, SMFixIt(Range, FixMsg),
3187 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3190 CC = StringSwitch<unsigned>(Name)
3226 if (!(isABI_N32() || isABI_N64()))
3229 if (12 <= CC && CC <= 15) {
3230 // Name is one of t4-t7
3231 AsmToken RegTok = getLexer().peekTok();
3232 SMRange RegRange = RegTok.getLocRange();
3234 StringRef FixedName = StringSwitch<StringRef>(Name)
3240 assert(FixedName != "" && "Register name is not one of t4-t7.");
3242 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3243 "Did you mean $" + FixedName + "?", RegRange);
3246 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3247 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3248 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3249 if (8 <= CC && CC <= 11)
3253 CC = StringSwitch<unsigned>(Name)
3265 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3268 CC = StringSwitch<unsigned>(Name)
3269 .Case("hwr_cpunum", 0)
3270 .Case("hwr_synci_step", 1)
3272 .Case("hwr_ccres", 3)
3273 .Case("hwr_ulr", 29)
3279 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3281 if (Name[0] == 'f') {
3282 StringRef NumString = Name.substr(1);
3284 if (NumString.getAsInteger(10, IntVal))
3285 return -1; // This is not an integer.
3286 if (IntVal > 31) // Maximum index for fpu register.
3293 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3295 if (Name.startswith("fcc")) {
3296 StringRef NumString = Name.substr(3);
3298 if (NumString.getAsInteger(10, IntVal))
3299 return -1; // This is not an integer.
3300 if (IntVal > 7) // There are only 8 fcc registers.
3307 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3309 if (Name.startswith("ac")) {
3310 StringRef NumString = Name.substr(2);
3312 if (NumString.getAsInteger(10, IntVal))
3313 return -1; // This is not an integer.
3314 if (IntVal > 3) // There are only 3 acc registers.
3321 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3324 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3333 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3336 CC = StringSwitch<unsigned>(Name)
3339 .Case("msaaccess", 2)
3341 .Case("msamodify", 4)
3342 .Case("msarequest", 5)
3344 .Case("msaunmap", 7)
3350 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3351 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3353 reportParseError(Loc,
3354 "pseudo-instruction requires $at, which is not available");
3357 unsigned AT = getReg(
3358 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3362 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3363 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3366 unsigned MipsAsmParser::getGPR(int RegNo) {
3367 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3371 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3373 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3376 return getReg(RegClass, RegNum);
3379 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3380 MCAsmParser &Parser = getParser();
3381 DEBUG(dbgs() << "parseOperand\n");
3383 // Check if the current operand has a custom associated parser, if so, try to
3384 // custom parse the operand, or fallback to the general approach.
3385 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3386 if (ResTy == MatchOperand_Success)
3388 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3389 // there was a match, but an error occurred, in which case, just return that
3390 // the operand parsing failed.
3391 if (ResTy == MatchOperand_ParseFail)
3394 DEBUG(dbgs() << ".. Generic Parser\n");
3396 switch (getLexer().getKind()) {
3398 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3400 case AsmToken::Dollar: {
3401 // Parse the register.
3402 SMLoc S = Parser.getTok().getLoc();
3404 // Almost all registers have been parsed by custom parsers. There is only
3405 // one exception to this. $zero (and it's alias $0) will reach this point
3406 // for div, divu, and similar instructions because it is not an operand
3407 // to the instruction definition but an explicit register. Special case
3408 // this situation for now.
3409 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3412 // Maybe it is a symbol reference.
3413 StringRef Identifier;
3414 if (Parser.parseIdentifier(Identifier))
3417 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3418 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3419 // Otherwise create a symbol reference.
3421 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3423 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3426 // Else drop to expression parsing.
3427 case AsmToken::LParen:
3428 case AsmToken::Minus:
3429 case AsmToken::Plus:
3430 case AsmToken::Integer:
3431 case AsmToken::Tilde:
3432 case AsmToken::String: {
3433 DEBUG(dbgs() << ".. generic integer\n");
3434 OperandMatchResultTy ResTy = parseImm(Operands);
3435 return ResTy != MatchOperand_Success;
3437 case AsmToken::Percent: {
3438 // It is a symbol reference or constant expression.
3439 const MCExpr *IdVal;
3440 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3441 if (parseRelocOperand(IdVal))
3444 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3446 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3448 } // case AsmToken::Percent
3449 } // switch(getLexer().getKind())
3453 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3454 StringRef RelocStr) {
3456 // Check the type of the expression.
3457 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3458 // It's a constant, evaluate reloc value.
3460 switch (getVariantKind(RelocStr)) {
3461 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3462 // Get the 1st 16-bits.
3463 Val = MCE->getValue() & 0xffff;
3465 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3466 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3467 // 16 bits being negative.
3468 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3470 case MCSymbolRefExpr::VK_Mips_HIGHER:
3471 // Get the 3rd 16-bits.
3472 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3474 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3475 // Get the 4th 16-bits.
3476 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3479 report_fatal_error("unsupported reloc value");
3481 return MCConstantExpr::create(Val, getContext());
3484 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3485 // It's a symbol, create a symbolic expression from the symbol.
3486 const MCSymbol *Symbol = &MSRE->getSymbol();
3487 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3488 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3492 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3493 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3495 // Try to create target expression.
3496 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3497 return MipsMCExpr::create(VK, Expr, getContext());
3499 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3500 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3501 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3505 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3506 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3507 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3510 // Just return the original expression.
3514 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3516 switch (Expr->getKind()) {
3517 case MCExpr::Constant:
3519 case MCExpr::SymbolRef:
3520 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3521 case MCExpr::Binary:
3522 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3523 if (!isEvaluated(BE->getLHS()))
3525 return isEvaluated(BE->getRHS());
3528 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3529 case MCExpr::Target:
3535 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3536 MCAsmParser &Parser = getParser();
3537 Parser.Lex(); // Eat the % token.
3538 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3539 if (Tok.isNot(AsmToken::Identifier))
3542 std::string Str = Tok.getIdentifier();
3544 Parser.Lex(); // Eat the identifier.
3545 // Now make an expression from the rest of the operand.
3546 const MCExpr *IdVal;
3549 if (getLexer().getKind() == AsmToken::LParen) {
3551 Parser.Lex(); // Eat the '(' token.
3552 if (getLexer().getKind() == AsmToken::Percent) {
3553 Parser.Lex(); // Eat the % token.
3554 const AsmToken &nextTok = Parser.getTok();
3555 if (nextTok.isNot(AsmToken::Identifier))
3558 Str += nextTok.getIdentifier();
3559 Parser.Lex(); // Eat the identifier.
3560 if (getLexer().getKind() != AsmToken::LParen)
3565 if (getParser().parseParenExpression(IdVal, EndLoc))
3568 while (getLexer().getKind() == AsmToken::RParen)
3569 Parser.Lex(); // Eat the ')' token.
3572 return true; // Parenthesis must follow the relocation operand.
3574 Res = evaluateRelocExpr(IdVal, Str);
3578 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3580 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3581 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3582 if (ResTy == MatchOperand_Success) {
3583 assert(Operands.size() == 1);
3584 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3585 StartLoc = Operand.getStartLoc();
3586 EndLoc = Operand.getEndLoc();
3588 // AFAIK, we only support numeric registers and named GPR's in CFI
3590 // Don't worry about eating tokens before failing. Using an unrecognised
3591 // register is a parse error.
3592 if (Operand.isGPRAsmReg()) {
3593 // Resolve to GPR32 or GPR64 appropriately.
3594 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3597 return (RegNo == (unsigned)-1);
3600 assert(Operands.size() == 0);
3601 return (RegNo == (unsigned)-1);
3604 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3605 MCAsmParser &Parser = getParser();
3608 unsigned NumOfLParen = 0;
3610 while (getLexer().getKind() == AsmToken::LParen) {
3615 switch (getLexer().getKind()) {
3618 case AsmToken::Identifier:
3619 case AsmToken::LParen:
3620 case AsmToken::Integer:
3621 case AsmToken::Minus:
3622 case AsmToken::Plus:
3624 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3626 Result = (getParser().parseExpression(Res));
3627 while (getLexer().getKind() == AsmToken::RParen)
3630 case AsmToken::Percent:
3631 Result = parseRelocOperand(Res);
3636 MipsAsmParser::OperandMatchResultTy
3637 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3638 MCAsmParser &Parser = getParser();
3639 DEBUG(dbgs() << "parseMemOperand\n");
3640 const MCExpr *IdVal = nullptr;
3642 bool isParenExpr = false;
3643 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3644 // First operand is the offset.
3645 S = Parser.getTok().getLoc();
3647 if (getLexer().getKind() == AsmToken::LParen) {
3652 if (getLexer().getKind() != AsmToken::Dollar) {
3653 if (parseMemOffset(IdVal, isParenExpr))
3654 return MatchOperand_ParseFail;
3656 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3657 if (Tok.isNot(AsmToken::LParen)) {
3658 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3659 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3661 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3662 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3663 return MatchOperand_Success;
3665 if (Tok.is(AsmToken::EndOfStatement)) {
3667 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3669 // Zero register assumed, add a memory operand with ZERO as its base.
3670 // "Base" will be managed by k_Memory.
3671 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3674 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3675 return MatchOperand_Success;
3677 Error(Parser.getTok().getLoc(), "'(' expected");
3678 return MatchOperand_ParseFail;
3681 Parser.Lex(); // Eat the '(' token.
3684 Res = parseAnyRegister(Operands);
3685 if (Res != MatchOperand_Success)
3688 if (Parser.getTok().isNot(AsmToken::RParen)) {
3689 Error(Parser.getTok().getLoc(), "')' expected");
3690 return MatchOperand_ParseFail;
3693 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3695 Parser.Lex(); // Eat the ')' token.
3698 IdVal = MCConstantExpr::create(0, getContext());
3700 // Replace the register operand with the memory operand.
3701 std::unique_ptr<MipsOperand> op(
3702 static_cast<MipsOperand *>(Operands.back().release()));
3703 // Remove the register from the operands.
3704 // "op" will be managed by k_Memory.
3705 Operands.pop_back();
3706 // Add the memory operand.
3707 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3709 if (IdVal->evaluateAsAbsolute(Imm))
3710 IdVal = MCConstantExpr::create(Imm, getContext());
3711 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3712 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3716 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3717 return MatchOperand_Success;
3720 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3721 MCAsmParser &Parser = getParser();
3722 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3724 SMLoc S = Parser.getTok().getLoc();
3726 if (Sym->isVariable())
3727 Expr = Sym->getVariableValue();
3730 if (Expr->getKind() == MCExpr::SymbolRef) {
3731 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3732 StringRef DefSymbol = Ref->getSymbol().getName();
3733 if (DefSymbol.startswith("$")) {
3734 OperandMatchResultTy ResTy =
3735 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3736 if (ResTy == MatchOperand_Success) {
3739 } else if (ResTy == MatchOperand_ParseFail)
3740 llvm_unreachable("Should never ParseFail");
3743 } else if (Expr->getKind() == MCExpr::Constant) {
3745 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3747 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3754 MipsAsmParser::OperandMatchResultTy
3755 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3756 StringRef Identifier,
3758 int Index = matchCPURegisterName(Identifier);
3760 Operands.push_back(MipsOperand::createGPRReg(
3761 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3762 return MatchOperand_Success;
3765 Index = matchHWRegsRegisterName(Identifier);
3767 Operands.push_back(MipsOperand::createHWRegsReg(
3768 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3769 return MatchOperand_Success;
3772 Index = matchFPURegisterName(Identifier);
3774 Operands.push_back(MipsOperand::createFGRReg(
3775 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3776 return MatchOperand_Success;
3779 Index = matchFCCRegisterName(Identifier);
3781 Operands.push_back(MipsOperand::createFCCReg(
3782 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3783 return MatchOperand_Success;
3786 Index = matchACRegisterName(Identifier);
3788 Operands.push_back(MipsOperand::createACCReg(
3789 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3790 return MatchOperand_Success;
3793 Index = matchMSA128RegisterName(Identifier);
3795 Operands.push_back(MipsOperand::createMSA128Reg(
3796 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3797 return MatchOperand_Success;
3800 Index = matchMSA128CtrlRegisterName(Identifier);
3802 Operands.push_back(MipsOperand::createMSACtrlReg(
3803 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3804 return MatchOperand_Success;
3807 return MatchOperand_NoMatch;
3810 MipsAsmParser::OperandMatchResultTy
3811 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3812 MCAsmParser &Parser = getParser();
3813 auto Token = Parser.getLexer().peekTok(false);
3815 if (Token.is(AsmToken::Identifier)) {
3816 DEBUG(dbgs() << ".. identifier\n");
3817 StringRef Identifier = Token.getIdentifier();
3818 OperandMatchResultTy ResTy =
3819 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3821 } else if (Token.is(AsmToken::Integer)) {
3822 DEBUG(dbgs() << ".. integer\n");
3823 Operands.push_back(MipsOperand::createNumericReg(
3824 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3826 return MatchOperand_Success;
3829 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3831 return MatchOperand_NoMatch;
3834 MipsAsmParser::OperandMatchResultTy
3835 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3836 MCAsmParser &Parser = getParser();
3837 DEBUG(dbgs() << "parseAnyRegister\n");
3839 auto Token = Parser.getTok();
3841 SMLoc S = Token.getLoc();
3843 if (Token.isNot(AsmToken::Dollar)) {
3844 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3845 if (Token.is(AsmToken::Identifier)) {
3846 if (searchSymbolAlias(Operands))
3847 return MatchOperand_Success;
3849 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3850 return MatchOperand_NoMatch;
3852 DEBUG(dbgs() << ".. $\n");
3854 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3855 if (ResTy == MatchOperand_Success) {
3857 Parser.Lex(); // identifier
3862 MipsAsmParser::OperandMatchResultTy
3863 MipsAsmParser::parseImm(OperandVector &Operands) {
3864 MCAsmParser &Parser = getParser();
3865 switch (getLexer().getKind()) {
3867 return MatchOperand_NoMatch;
3868 case AsmToken::LParen:
3869 case AsmToken::Minus:
3870 case AsmToken::Plus:
3871 case AsmToken::Integer:
3872 case AsmToken::Tilde:
3873 case AsmToken::String:
3877 const MCExpr *IdVal;
3878 SMLoc S = Parser.getTok().getLoc();
3879 if (getParser().parseExpression(IdVal))
3880 return MatchOperand_ParseFail;
3882 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3883 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3884 return MatchOperand_Success;
3887 MipsAsmParser::OperandMatchResultTy
3888 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3889 MCAsmParser &Parser = getParser();
3890 DEBUG(dbgs() << "parseJumpTarget\n");
3892 SMLoc S = getLexer().getLoc();
3894 // Integers and expressions are acceptable
3895 OperandMatchResultTy ResTy = parseImm(Operands);
3896 if (ResTy != MatchOperand_NoMatch)
3899 // Registers are a valid target and have priority over symbols.
3900 ResTy = parseAnyRegister(Operands);
3901 if (ResTy != MatchOperand_NoMatch)
3904 const MCExpr *Expr = nullptr;
3905 if (Parser.parseExpression(Expr)) {
3906 // We have no way of knowing if a symbol was consumed so we must ParseFail
3907 return MatchOperand_ParseFail;
3910 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3911 return MatchOperand_Success;
3914 MipsAsmParser::OperandMatchResultTy
3915 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3916 MCAsmParser &Parser = getParser();
3917 const MCExpr *IdVal;
3918 // If the first token is '$' we may have register operand.
3919 if (Parser.getTok().is(AsmToken::Dollar))
3920 return MatchOperand_NoMatch;
3921 SMLoc S = Parser.getTok().getLoc();
3922 if (getParser().parseExpression(IdVal))
3923 return MatchOperand_ParseFail;
3924 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3925 assert(MCE && "Unexpected MCExpr type.");
3926 int64_t Val = MCE->getValue();
3927 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3928 Operands.push_back(MipsOperand::CreateImm(
3929 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3930 return MatchOperand_Success;
3933 MipsAsmParser::OperandMatchResultTy
3934 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3935 MCAsmParser &Parser = getParser();
3936 switch (getLexer().getKind()) {
3938 return MatchOperand_NoMatch;
3939 case AsmToken::LParen:
3940 case AsmToken::Plus:
3941 case AsmToken::Minus:
3942 case AsmToken::Integer:
3947 SMLoc S = Parser.getTok().getLoc();
3949 if (getParser().parseExpression(Expr))
3950 return MatchOperand_ParseFail;
3953 if (!Expr->evaluateAsAbsolute(Val)) {
3954 Error(S, "expected immediate value");
3955 return MatchOperand_ParseFail;
3958 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3959 // and because the CPU always adds one to the immediate field, the allowed
3960 // range becomes 1..4. We'll only check the range here and will deal
3961 // with the addition/subtraction when actually decoding/encoding
3963 if (Val < 1 || Val > 4) {
3964 Error(S, "immediate not in range (1..4)");
3965 return MatchOperand_ParseFail;
3969 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3970 return MatchOperand_Success;
3973 MipsAsmParser::OperandMatchResultTy
3974 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3975 MCAsmParser &Parser = getParser();
3976 SmallVector<unsigned, 10> Regs;
3978 unsigned PrevReg = Mips::NoRegister;
3979 bool RegRange = false;
3980 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3982 if (Parser.getTok().isNot(AsmToken::Dollar))
3983 return MatchOperand_ParseFail;
3985 SMLoc S = Parser.getTok().getLoc();
3986 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3987 SMLoc E = getLexer().getLoc();
3988 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3989 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3991 // Remove last register operand because registers from register range
3992 // should be inserted first.
3993 if (RegNo == Mips::RA) {
3994 Regs.push_back(RegNo);
3996 unsigned TmpReg = PrevReg + 1;
3997 while (TmpReg <= RegNo) {
3998 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3999 Error(E, "invalid register operand");
4000 return MatchOperand_ParseFail;
4004 Regs.push_back(TmpReg++);
4010 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4011 (RegNo != Mips::RA)) {
4012 Error(E, "$16 or $31 expected");
4013 return MatchOperand_ParseFail;
4014 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4015 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4016 Error(E, "invalid register operand");
4017 return MatchOperand_ParseFail;
4018 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4019 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4020 Error(E, "consecutive register numbers expected");
4021 return MatchOperand_ParseFail;
4024 Regs.push_back(RegNo);
4027 if (Parser.getTok().is(AsmToken::Minus))
4030 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4031 !Parser.getTok().isNot(AsmToken::Comma)) {
4032 Error(E, "',' or '-' expected");
4033 return MatchOperand_ParseFail;
4036 Lex(); // Consume comma or minus
4037 if (Parser.getTok().isNot(AsmToken::Dollar))
4043 SMLoc E = Parser.getTok().getLoc();
4044 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4045 parseMemOperand(Operands);
4046 return MatchOperand_Success;
4049 MipsAsmParser::OperandMatchResultTy
4050 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4051 MCAsmParser &Parser = getParser();
4053 SMLoc S = Parser.getTok().getLoc();
4054 if (parseAnyRegister(Operands) != MatchOperand_Success)
4055 return MatchOperand_ParseFail;
4057 SMLoc E = Parser.getTok().getLoc();
4058 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4059 unsigned Reg = Op.getGPR32Reg();
4060 Operands.pop_back();
4061 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4062 return MatchOperand_Success;
4065 MipsAsmParser::OperandMatchResultTy
4066 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4067 MCAsmParser &Parser = getParser();
4068 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4069 SmallVector<unsigned, 10> Regs;
4071 if (Parser.getTok().isNot(AsmToken::Dollar))
4072 return MatchOperand_ParseFail;
4074 SMLoc S = Parser.getTok().getLoc();
4076 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4077 return MatchOperand_ParseFail;
4079 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4080 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4081 Regs.push_back(RegNo);
4083 SMLoc E = Parser.getTok().getLoc();
4084 if (Parser.getTok().isNot(AsmToken::Comma)) {
4085 Error(E, "',' expected");
4086 return MatchOperand_ParseFail;
4092 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4093 return MatchOperand_ParseFail;
4095 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4096 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4097 Regs.push_back(RegNo);
4099 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4101 return MatchOperand_Success;
4104 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4106 MCSymbolRefExpr::VariantKind VK =
4107 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4108 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4109 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4110 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4111 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4112 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4113 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4114 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4115 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4116 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4117 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4118 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4119 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4120 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4121 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4122 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4123 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4124 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4125 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4126 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4127 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4128 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4129 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4130 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4131 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4132 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4133 .Default(MCSymbolRefExpr::VK_None);
4135 assert(VK != MCSymbolRefExpr::VK_None);
4140 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4142 /// ::= '(', register, ')'
4143 /// handle it before we iterate so we don't get tripped up by the lack of
4145 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4146 MCAsmParser &Parser = getParser();
4147 if (getLexer().is(AsmToken::LParen)) {
4149 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4151 if (parseOperand(Operands, Name)) {
4152 SMLoc Loc = getLexer().getLoc();
4153 Parser.eatToEndOfStatement();
4154 return Error(Loc, "unexpected token in argument list");
4156 if (Parser.getTok().isNot(AsmToken::RParen)) {
4157 SMLoc Loc = getLexer().getLoc();
4158 Parser.eatToEndOfStatement();
4159 return Error(Loc, "unexpected token, expected ')'");
4162 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4168 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4169 /// either one of these.
4170 /// ::= '[', register, ']'
4171 /// ::= '[', integer, ']'
4172 /// handle it before we iterate so we don't get tripped up by the lack of
4174 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4175 OperandVector &Operands) {
4176 MCAsmParser &Parser = getParser();
4177 if (getLexer().is(AsmToken::LBrac)) {
4179 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4181 if (parseOperand(Operands, Name)) {
4182 SMLoc Loc = getLexer().getLoc();
4183 Parser.eatToEndOfStatement();
4184 return Error(Loc, "unexpected token in argument list");
4186 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4187 SMLoc Loc = getLexer().getLoc();
4188 Parser.eatToEndOfStatement();
4189 return Error(Loc, "unexpected token, expected ']'");
4192 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4198 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4199 SMLoc NameLoc, OperandVector &Operands) {
4200 MCAsmParser &Parser = getParser();
4201 DEBUG(dbgs() << "ParseInstruction\n");
4203 // We have reached first instruction, module directive are now forbidden.
4204 getTargetStreamer().forbidModuleDirective();
4206 // Check if we have valid mnemonic
4207 if (!mnemonicIsValid(Name, 0)) {
4208 Parser.eatToEndOfStatement();
4209 return Error(NameLoc, "unknown instruction");
4211 // First operand in MCInst is instruction mnemonic.
4212 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4214 // Read the remaining operands.
4215 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4216 // Read the first operand.
4217 if (parseOperand(Operands, Name)) {
4218 SMLoc Loc = getLexer().getLoc();
4219 Parser.eatToEndOfStatement();
4220 return Error(Loc, "unexpected token in argument list");
4222 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4224 // AFAIK, parenthesis suffixes are never on the first operand
4226 while (getLexer().is(AsmToken::Comma)) {
4227 Parser.Lex(); // Eat the comma.
4228 // Parse and remember the operand.
4229 if (parseOperand(Operands, Name)) {
4230 SMLoc Loc = getLexer().getLoc();
4231 Parser.eatToEndOfStatement();
4232 return Error(Loc, "unexpected token in argument list");
4234 // Parse bracket and parenthesis suffixes before we iterate
4235 if (getLexer().is(AsmToken::LBrac)) {
4236 if (parseBracketSuffix(Name, Operands))
4238 } else if (getLexer().is(AsmToken::LParen) &&
4239 parseParenSuffix(Name, Operands))
4243 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4244 SMLoc Loc = getLexer().getLoc();
4245 Parser.eatToEndOfStatement();
4246 return Error(Loc, "unexpected token in argument list");
4248 Parser.Lex(); // Consume the EndOfStatement.
4252 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4253 MCAsmParser &Parser = getParser();
4254 SMLoc Loc = getLexer().getLoc();
4255 Parser.eatToEndOfStatement();
4256 return Error(Loc, ErrorMsg);
4259 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4260 return Error(Loc, ErrorMsg);
4263 bool MipsAsmParser::parseSetNoAtDirective() {
4264 MCAsmParser &Parser = getParser();
4265 // Line should look like: ".set noat".
4267 // Set the $at register to $0.
4268 AssemblerOptions.back()->setATRegIndex(0);
4270 Parser.Lex(); // Eat "noat".
4272 // If this is not the end of the statement, report an error.
4273 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4274 reportParseError("unexpected token, expected end of statement");
4278 getTargetStreamer().emitDirectiveSetNoAt();
4279 Parser.Lex(); // Consume the EndOfStatement.
4283 bool MipsAsmParser::parseSetAtDirective() {
4284 // Line can be: ".set at", which sets $at to $1
4285 // or ".set at=$reg", which sets $at to $reg.
4286 MCAsmParser &Parser = getParser();
4287 Parser.Lex(); // Eat "at".
4289 if (getLexer().is(AsmToken::EndOfStatement)) {
4290 // No register was specified, so we set $at to $1.
4291 AssemblerOptions.back()->setATRegIndex(1);
4293 getTargetStreamer().emitDirectiveSetAt();
4294 Parser.Lex(); // Consume the EndOfStatement.
4298 if (getLexer().isNot(AsmToken::Equal)) {
4299 reportParseError("unexpected token, expected equals sign");
4302 Parser.Lex(); // Eat "=".
4304 if (getLexer().isNot(AsmToken::Dollar)) {
4305 if (getLexer().is(AsmToken::EndOfStatement)) {
4306 reportParseError("no register specified");
4309 reportParseError("unexpected token, expected dollar sign '$'");
4313 Parser.Lex(); // Eat "$".
4315 // Find out what "reg" is.
4317 const AsmToken &Reg = Parser.getTok();
4318 if (Reg.is(AsmToken::Identifier)) {
4319 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4320 } else if (Reg.is(AsmToken::Integer)) {
4321 AtRegNo = Reg.getIntVal();
4323 reportParseError("unexpected token, expected identifier or integer");
4327 // Check if $reg is a valid register. If it is, set $at to $reg.
4328 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4329 reportParseError("invalid register");
4332 Parser.Lex(); // Eat "reg".
4334 // If this is not the end of the statement, report an error.
4335 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4336 reportParseError("unexpected token, expected end of statement");
4340 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4342 Parser.Lex(); // Consume the EndOfStatement.
4346 bool MipsAsmParser::parseSetReorderDirective() {
4347 MCAsmParser &Parser = getParser();
4349 // If this is not the end of the statement, report an error.
4350 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4351 reportParseError("unexpected token, expected end of statement");
4354 AssemblerOptions.back()->setReorder();
4355 getTargetStreamer().emitDirectiveSetReorder();
4356 Parser.Lex(); // Consume the EndOfStatement.
4360 bool MipsAsmParser::parseSetNoReorderDirective() {
4361 MCAsmParser &Parser = getParser();
4363 // If this is not the end of the statement, report an error.
4364 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4365 reportParseError("unexpected token, expected end of statement");
4368 AssemblerOptions.back()->setNoReorder();
4369 getTargetStreamer().emitDirectiveSetNoReorder();
4370 Parser.Lex(); // Consume the EndOfStatement.
4374 bool MipsAsmParser::parseSetMacroDirective() {
4375 MCAsmParser &Parser = getParser();
4377 // If this is not the end of the statement, report an error.
4378 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4379 reportParseError("unexpected token, expected end of statement");
4382 AssemblerOptions.back()->setMacro();
4383 getTargetStreamer().emitDirectiveSetMacro();
4384 Parser.Lex(); // Consume the EndOfStatement.
4388 bool MipsAsmParser::parseSetNoMacroDirective() {
4389 MCAsmParser &Parser = getParser();
4391 // If this is not the end of the statement, report an error.
4392 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4393 reportParseError("unexpected token, expected end of statement");
4396 if (AssemblerOptions.back()->isReorder()) {
4397 reportParseError("`noreorder' must be set before `nomacro'");
4400 AssemblerOptions.back()->setNoMacro();
4401 getTargetStreamer().emitDirectiveSetNoMacro();
4402 Parser.Lex(); // Consume the EndOfStatement.
4406 bool MipsAsmParser::parseSetMsaDirective() {
4407 MCAsmParser &Parser = getParser();
4410 // If this is not the end of the statement, report an error.
4411 if (getLexer().isNot(AsmToken::EndOfStatement))
4412 return reportParseError("unexpected token, expected end of statement");
4414 setFeatureBits(Mips::FeatureMSA, "msa");
4415 getTargetStreamer().emitDirectiveSetMsa();
4419 bool MipsAsmParser::parseSetNoMsaDirective() {
4420 MCAsmParser &Parser = getParser();
4423 // If this is not the end of the statement, report an error.
4424 if (getLexer().isNot(AsmToken::EndOfStatement))
4425 return reportParseError("unexpected token, expected end of statement");
4427 clearFeatureBits(Mips::FeatureMSA, "msa");
4428 getTargetStreamer().emitDirectiveSetNoMsa();
4432 bool MipsAsmParser::parseSetNoDspDirective() {
4433 MCAsmParser &Parser = getParser();
4434 Parser.Lex(); // Eat "nodsp".
4436 // If this is not the end of the statement, report an error.
4437 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4438 reportParseError("unexpected token, expected end of statement");
4442 clearFeatureBits(Mips::FeatureDSP, "dsp");
4443 getTargetStreamer().emitDirectiveSetNoDsp();
4447 bool MipsAsmParser::parseSetMips16Directive() {
4448 MCAsmParser &Parser = getParser();
4449 Parser.Lex(); // Eat "mips16".
4451 // If this is not the end of the statement, report an error.
4452 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4453 reportParseError("unexpected token, expected end of statement");
4457 setFeatureBits(Mips::FeatureMips16, "mips16");
4458 getTargetStreamer().emitDirectiveSetMips16();
4459 Parser.Lex(); // Consume the EndOfStatement.
4463 bool MipsAsmParser::parseSetNoMips16Directive() {
4464 MCAsmParser &Parser = getParser();
4465 Parser.Lex(); // Eat "nomips16".
4467 // If this is not the end of the statement, report an error.
4468 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4469 reportParseError("unexpected token, expected end of statement");
4473 clearFeatureBits(Mips::FeatureMips16, "mips16");
4474 getTargetStreamer().emitDirectiveSetNoMips16();
4475 Parser.Lex(); // Consume the EndOfStatement.
4479 bool MipsAsmParser::parseSetFpDirective() {
4480 MCAsmParser &Parser = getParser();
4481 MipsABIFlagsSection::FpABIKind FpAbiVal;
4482 // Line can be: .set fp=32
4485 Parser.Lex(); // Eat fp token
4486 AsmToken Tok = Parser.getTok();
4487 if (Tok.isNot(AsmToken::Equal)) {
4488 reportParseError("unexpected token, expected equals sign '='");
4491 Parser.Lex(); // Eat '=' token.
4492 Tok = Parser.getTok();
4494 if (!parseFpABIValue(FpAbiVal, ".set"))
4497 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4498 reportParseError("unexpected token, expected end of statement");
4501 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4502 Parser.Lex(); // Consume the EndOfStatement.
4506 bool MipsAsmParser::parseSetOddSPRegDirective() {
4507 MCAsmParser &Parser = getParser();
4509 Parser.Lex(); // Eat "oddspreg".
4510 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4511 reportParseError("unexpected token, expected end of statement");
4515 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4516 getTargetStreamer().emitDirectiveSetOddSPReg();
4520 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4521 MCAsmParser &Parser = getParser();
4523 Parser.Lex(); // Eat "nooddspreg".
4524 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4525 reportParseError("unexpected token, expected end of statement");
4529 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4530 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4534 bool MipsAsmParser::parseSetPopDirective() {
4535 MCAsmParser &Parser = getParser();
4536 SMLoc Loc = getLexer().getLoc();
4539 if (getLexer().isNot(AsmToken::EndOfStatement))
4540 return reportParseError("unexpected token, expected end of statement");
4542 // Always keep an element on the options "stack" to prevent the user
4543 // from changing the initial options. This is how we remember them.
4544 if (AssemblerOptions.size() == 2)
4545 return reportParseError(Loc, ".set pop with no .set push");
4547 AssemblerOptions.pop_back();
4548 setAvailableFeatures(
4549 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4550 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4552 getTargetStreamer().emitDirectiveSetPop();
4556 bool MipsAsmParser::parseSetPushDirective() {
4557 MCAsmParser &Parser = getParser();
4559 if (getLexer().isNot(AsmToken::EndOfStatement))
4560 return reportParseError("unexpected token, expected end of statement");
4562 // Create a copy of the current assembler options environment and push it.
4563 AssemblerOptions.push_back(
4564 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4566 getTargetStreamer().emitDirectiveSetPush();
4570 bool MipsAsmParser::parseSetSoftFloatDirective() {
4571 MCAsmParser &Parser = getParser();
4573 if (getLexer().isNot(AsmToken::EndOfStatement))
4574 return reportParseError("unexpected token, expected end of statement");
4576 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4577 getTargetStreamer().emitDirectiveSetSoftFloat();
4581 bool MipsAsmParser::parseSetHardFloatDirective() {
4582 MCAsmParser &Parser = getParser();
4584 if (getLexer().isNot(AsmToken::EndOfStatement))
4585 return reportParseError("unexpected token, expected end of statement");
4587 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4588 getTargetStreamer().emitDirectiveSetHardFloat();
4592 bool MipsAsmParser::parseSetAssignment() {
4594 const MCExpr *Value;
4595 MCAsmParser &Parser = getParser();
4597 if (Parser.parseIdentifier(Name))
4598 reportParseError("expected identifier after .set");
4600 if (getLexer().isNot(AsmToken::Comma))
4601 return reportParseError("unexpected token, expected comma");
4604 if (Parser.parseExpression(Value))
4605 return reportParseError("expected valid expression after comma");
4607 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4608 Sym->setVariableValue(Value);
4613 bool MipsAsmParser::parseSetMips0Directive() {
4614 MCAsmParser &Parser = getParser();
4616 if (getLexer().isNot(AsmToken::EndOfStatement))
4617 return reportParseError("unexpected token, expected end of statement");
4619 // Reset assembler options to their initial values.
4620 setAvailableFeatures(
4621 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4622 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4623 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4625 getTargetStreamer().emitDirectiveSetMips0();
4629 bool MipsAsmParser::parseSetArchDirective() {
4630 MCAsmParser &Parser = getParser();
4632 if (getLexer().isNot(AsmToken::Equal))
4633 return reportParseError("unexpected token, expected equals sign");
4637 if (Parser.parseIdentifier(Arch))
4638 return reportParseError("expected arch identifier");
4640 StringRef ArchFeatureName =
4641 StringSwitch<StringRef>(Arch)
4642 .Case("mips1", "mips1")
4643 .Case("mips2", "mips2")
4644 .Case("mips3", "mips3")
4645 .Case("mips4", "mips4")
4646 .Case("mips5", "mips5")
4647 .Case("mips32", "mips32")
4648 .Case("mips32r2", "mips32r2")
4649 .Case("mips32r3", "mips32r3")
4650 .Case("mips32r5", "mips32r5")
4651 .Case("mips32r6", "mips32r6")
4652 .Case("mips64", "mips64")
4653 .Case("mips64r2", "mips64r2")
4654 .Case("mips64r3", "mips64r3")
4655 .Case("mips64r5", "mips64r5")
4656 .Case("mips64r6", "mips64r6")
4657 .Case("cnmips", "cnmips")
4658 .Case("r4000", "mips3") // This is an implementation of Mips3.
4661 if (ArchFeatureName.empty())
4662 return reportParseError("unsupported architecture");
4664 selectArch(ArchFeatureName);
4665 getTargetStreamer().emitDirectiveSetArch(Arch);
4669 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4670 MCAsmParser &Parser = getParser();
4672 if (getLexer().isNot(AsmToken::EndOfStatement))
4673 return reportParseError("unexpected token, expected end of statement");
4677 llvm_unreachable("Unimplemented feature");
4678 case Mips::FeatureDSP:
4679 setFeatureBits(Mips::FeatureDSP, "dsp");
4680 getTargetStreamer().emitDirectiveSetDsp();
4682 case Mips::FeatureMicroMips:
4683 getTargetStreamer().emitDirectiveSetMicroMips();
4685 case Mips::FeatureMips1:
4686 selectArch("mips1");
4687 getTargetStreamer().emitDirectiveSetMips1();
4689 case Mips::FeatureMips2:
4690 selectArch("mips2");
4691 getTargetStreamer().emitDirectiveSetMips2();
4693 case Mips::FeatureMips3:
4694 selectArch("mips3");
4695 getTargetStreamer().emitDirectiveSetMips3();
4697 case Mips::FeatureMips4:
4698 selectArch("mips4");
4699 getTargetStreamer().emitDirectiveSetMips4();
4701 case Mips::FeatureMips5:
4702 selectArch("mips5");
4703 getTargetStreamer().emitDirectiveSetMips5();
4705 case Mips::FeatureMips32:
4706 selectArch("mips32");
4707 getTargetStreamer().emitDirectiveSetMips32();
4709 case Mips::FeatureMips32r2:
4710 selectArch("mips32r2");
4711 getTargetStreamer().emitDirectiveSetMips32R2();
4713 case Mips::FeatureMips32r3:
4714 selectArch("mips32r3");
4715 getTargetStreamer().emitDirectiveSetMips32R3();
4717 case Mips::FeatureMips32r5:
4718 selectArch("mips32r5");
4719 getTargetStreamer().emitDirectiveSetMips32R5();
4721 case Mips::FeatureMips32r6:
4722 selectArch("mips32r6");
4723 getTargetStreamer().emitDirectiveSetMips32R6();
4725 case Mips::FeatureMips64:
4726 selectArch("mips64");
4727 getTargetStreamer().emitDirectiveSetMips64();
4729 case Mips::FeatureMips64r2:
4730 selectArch("mips64r2");
4731 getTargetStreamer().emitDirectiveSetMips64R2();
4733 case Mips::FeatureMips64r3:
4734 selectArch("mips64r3");
4735 getTargetStreamer().emitDirectiveSetMips64R3();
4737 case Mips::FeatureMips64r5:
4738 selectArch("mips64r5");
4739 getTargetStreamer().emitDirectiveSetMips64R5();
4741 case Mips::FeatureMips64r6:
4742 selectArch("mips64r6");
4743 getTargetStreamer().emitDirectiveSetMips64R6();
4749 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4750 MCAsmParser &Parser = getParser();
4751 if (getLexer().isNot(AsmToken::Comma)) {
4752 SMLoc Loc = getLexer().getLoc();
4753 Parser.eatToEndOfStatement();
4754 return Error(Loc, ErrorStr);
4757 Parser.Lex(); // Eat the comma.
4761 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4762 if (AssemblerOptions.back()->isReorder())
4763 Warning(Loc, ".cpload should be inside a noreorder section");
4765 if (inMips16Mode()) {
4766 reportParseError(".cpload is not supported in Mips16 mode");
4770 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4771 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4772 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4773 reportParseError("expected register containing function address");
4777 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4778 if (!RegOpnd.isGPRAsmReg()) {
4779 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4783 // If this is not the end of the statement, report an error.
4784 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4785 reportParseError("unexpected token, expected end of statement");
4789 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4793 bool MipsAsmParser::parseDirectiveCPSetup() {
4794 MCAsmParser &Parser = getParser();
4797 bool SaveIsReg = true;
4799 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4800 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4801 if (ResTy == MatchOperand_NoMatch) {
4802 reportParseError("expected register containing function address");
4803 Parser.eatToEndOfStatement();
4807 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4808 if (!FuncRegOpnd.isGPRAsmReg()) {
4809 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4810 Parser.eatToEndOfStatement();
4814 FuncReg = FuncRegOpnd.getGPR32Reg();
4817 if (!eatComma("unexpected token, expected comma"))
4820 ResTy = parseAnyRegister(TmpReg);
4821 if (ResTy == MatchOperand_NoMatch) {
4822 const AsmToken &Tok = Parser.getTok();
4823 if (Tok.is(AsmToken::Integer)) {
4824 Save = Tok.getIntVal();
4828 reportParseError("expected save register or stack offset");
4829 Parser.eatToEndOfStatement();
4833 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4834 if (!SaveOpnd.isGPRAsmReg()) {
4835 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4836 Parser.eatToEndOfStatement();
4839 Save = SaveOpnd.getGPR32Reg();
4842 if (!eatComma("unexpected token, expected comma"))
4846 if (Parser.parseExpression(Expr)) {
4847 reportParseError("expected expression");
4851 if (Expr->getKind() != MCExpr::SymbolRef) {
4852 reportParseError("expected symbol");
4855 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4857 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4862 bool MipsAsmParser::parseDirectiveNaN() {
4863 MCAsmParser &Parser = getParser();
4864 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4865 const AsmToken &Tok = Parser.getTok();
4867 if (Tok.getString() == "2008") {
4869 getTargetStreamer().emitDirectiveNaN2008();
4871 } else if (Tok.getString() == "legacy") {
4873 getTargetStreamer().emitDirectiveNaNLegacy();
4877 // If we don't recognize the option passed to the .nan
4878 // directive (e.g. no option or unknown option), emit an error.
4879 reportParseError("invalid option in .nan directive");
4883 bool MipsAsmParser::parseDirectiveSet() {
4884 MCAsmParser &Parser = getParser();
4885 // Get the next token.
4886 const AsmToken &Tok = Parser.getTok();
4888 if (Tok.getString() == "noat") {
4889 return parseSetNoAtDirective();
4890 } else if (Tok.getString() == "at") {
4891 return parseSetAtDirective();
4892 } else if (Tok.getString() == "arch") {
4893 return parseSetArchDirective();
4894 } else if (Tok.getString() == "fp") {
4895 return parseSetFpDirective();
4896 } else if (Tok.getString() == "oddspreg") {
4897 return parseSetOddSPRegDirective();
4898 } else if (Tok.getString() == "nooddspreg") {
4899 return parseSetNoOddSPRegDirective();
4900 } else if (Tok.getString() == "pop") {
4901 return parseSetPopDirective();
4902 } else if (Tok.getString() == "push") {
4903 return parseSetPushDirective();
4904 } else if (Tok.getString() == "reorder") {
4905 return parseSetReorderDirective();
4906 } else if (Tok.getString() == "noreorder") {
4907 return parseSetNoReorderDirective();
4908 } else if (Tok.getString() == "macro") {
4909 return parseSetMacroDirective();
4910 } else if (Tok.getString() == "nomacro") {
4911 return parseSetNoMacroDirective();
4912 } else if (Tok.getString() == "mips16") {
4913 return parseSetMips16Directive();
4914 } else if (Tok.getString() == "nomips16") {
4915 return parseSetNoMips16Directive();
4916 } else if (Tok.getString() == "nomicromips") {
4917 getTargetStreamer().emitDirectiveSetNoMicroMips();
4918 Parser.eatToEndOfStatement();
4920 } else if (Tok.getString() == "micromips") {
4921 return parseSetFeature(Mips::FeatureMicroMips);
4922 } else if (Tok.getString() == "mips0") {
4923 return parseSetMips0Directive();
4924 } else if (Tok.getString() == "mips1") {
4925 return parseSetFeature(Mips::FeatureMips1);
4926 } else if (Tok.getString() == "mips2") {
4927 return parseSetFeature(Mips::FeatureMips2);
4928 } else if (Tok.getString() == "mips3") {
4929 return parseSetFeature(Mips::FeatureMips3);
4930 } else if (Tok.getString() == "mips4") {
4931 return parseSetFeature(Mips::FeatureMips4);
4932 } else if (Tok.getString() == "mips5") {
4933 return parseSetFeature(Mips::FeatureMips5);
4934 } else if (Tok.getString() == "mips32") {
4935 return parseSetFeature(Mips::FeatureMips32);
4936 } else if (Tok.getString() == "mips32r2") {
4937 return parseSetFeature(Mips::FeatureMips32r2);
4938 } else if (Tok.getString() == "mips32r3") {
4939 return parseSetFeature(Mips::FeatureMips32r3);
4940 } else if (Tok.getString() == "mips32r5") {
4941 return parseSetFeature(Mips::FeatureMips32r5);
4942 } else if (Tok.getString() == "mips32r6") {
4943 return parseSetFeature(Mips::FeatureMips32r6);
4944 } else if (Tok.getString() == "mips64") {
4945 return parseSetFeature(Mips::FeatureMips64);
4946 } else if (Tok.getString() == "mips64r2") {
4947 return parseSetFeature(Mips::FeatureMips64r2);
4948 } else if (Tok.getString() == "mips64r3") {
4949 return parseSetFeature(Mips::FeatureMips64r3);
4950 } else if (Tok.getString() == "mips64r5") {
4951 return parseSetFeature(Mips::FeatureMips64r5);
4952 } else if (Tok.getString() == "mips64r6") {
4953 return parseSetFeature(Mips::FeatureMips64r6);
4954 } else if (Tok.getString() == "dsp") {
4955 return parseSetFeature(Mips::FeatureDSP);
4956 } else if (Tok.getString() == "nodsp") {
4957 return parseSetNoDspDirective();
4958 } else if (Tok.getString() == "msa") {
4959 return parseSetMsaDirective();
4960 } else if (Tok.getString() == "nomsa") {
4961 return parseSetNoMsaDirective();
4962 } else if (Tok.getString() == "softfloat") {
4963 return parseSetSoftFloatDirective();
4964 } else if (Tok.getString() == "hardfloat") {
4965 return parseSetHardFloatDirective();
4967 // It is just an identifier, look for an assignment.
4968 parseSetAssignment();
4975 /// parseDataDirective
4976 /// ::= .word [ expression (, expression)* ]
4977 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4978 MCAsmParser &Parser = getParser();
4979 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4981 const MCExpr *Value;
4982 if (getParser().parseExpression(Value))
4985 getParser().getStreamer().EmitValue(Value, Size);
4987 if (getLexer().is(AsmToken::EndOfStatement))
4990 if (getLexer().isNot(AsmToken::Comma))
4991 return Error(L, "unexpected token, expected comma");
5000 /// parseDirectiveGpWord
5001 /// ::= .gpword local_sym
5002 bool MipsAsmParser::parseDirectiveGpWord() {
5003 MCAsmParser &Parser = getParser();
5004 const MCExpr *Value;
5005 // EmitGPRel32Value requires an expression, so we are using base class
5006 // method to evaluate the expression.
5007 if (getParser().parseExpression(Value))
5009 getParser().getStreamer().EmitGPRel32Value(Value);
5011 if (getLexer().isNot(AsmToken::EndOfStatement))
5012 return Error(getLexer().getLoc(),
5013 "unexpected token, expected end of statement");
5014 Parser.Lex(); // Eat EndOfStatement token.
5018 /// parseDirectiveGpDWord
5019 /// ::= .gpdword local_sym
5020 bool MipsAsmParser::parseDirectiveGpDWord() {
5021 MCAsmParser &Parser = getParser();
5022 const MCExpr *Value;
5023 // EmitGPRel64Value requires an expression, so we are using base class
5024 // method to evaluate the expression.
5025 if (getParser().parseExpression(Value))
5027 getParser().getStreamer().EmitGPRel64Value(Value);
5029 if (getLexer().isNot(AsmToken::EndOfStatement))
5030 return Error(getLexer().getLoc(),
5031 "unexpected token, expected end of statement");
5032 Parser.Lex(); // Eat EndOfStatement token.
5036 bool MipsAsmParser::parseDirectiveOption() {
5037 MCAsmParser &Parser = getParser();
5038 // Get the option token.
5039 AsmToken Tok = Parser.getTok();
5040 // At the moment only identifiers are supported.
5041 if (Tok.isNot(AsmToken::Identifier)) {
5042 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5043 Parser.eatToEndOfStatement();
5047 StringRef Option = Tok.getIdentifier();
5049 if (Option == "pic0") {
5050 // MipsAsmParser needs to know if the current PIC mode changes.
5051 IsPicEnabled = false;
5053 getTargetStreamer().emitDirectiveOptionPic0();
5055 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5056 Error(Parser.getTok().getLoc(),
5057 "unexpected token, expected end of statement");
5058 Parser.eatToEndOfStatement();
5063 if (Option == "pic2") {
5064 // MipsAsmParser needs to know if the current PIC mode changes.
5065 IsPicEnabled = true;
5067 getTargetStreamer().emitDirectiveOptionPic2();
5069 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5070 Error(Parser.getTok().getLoc(),
5071 "unexpected token, expected end of statement");
5072 Parser.eatToEndOfStatement();
5078 Warning(Parser.getTok().getLoc(),
5079 "unknown option, expected 'pic0' or 'pic2'");
5080 Parser.eatToEndOfStatement();
5084 /// parseInsnDirective
5086 bool MipsAsmParser::parseInsnDirective() {
5087 // If this is not the end of the statement, report an error.
5088 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5089 reportParseError("unexpected token, expected end of statement");
5093 // The actual label marking happens in
5094 // MipsELFStreamer::createPendingLabelRelocs().
5095 getTargetStreamer().emitDirectiveInsn();
5097 getParser().Lex(); // Eat EndOfStatement token.
5101 /// parseDirectiveModule
5102 /// ::= .module oddspreg
5103 /// ::= .module nooddspreg
5104 /// ::= .module fp=value
5105 /// ::= .module softfloat
5106 /// ::= .module hardfloat
5107 bool MipsAsmParser::parseDirectiveModule() {
5108 MCAsmParser &Parser = getParser();
5109 MCAsmLexer &Lexer = getLexer();
5110 SMLoc L = Lexer.getLoc();
5112 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5113 // TODO : get a better message.
5114 reportParseError(".module directive must appear before any code");
5119 if (Parser.parseIdentifier(Option)) {
5120 reportParseError("expected .module option identifier");
5124 if (Option == "oddspreg") {
5125 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5127 // Synchronize the abiflags information with the FeatureBits information we
5129 getTargetStreamer().updateABIInfo(*this);
5131 // If printing assembly, use the recently updated abiflags information.
5132 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5133 // emitted at the end).
5134 getTargetStreamer().emitDirectiveModuleOddSPReg();
5136 // If this is not the end of the statement, report an error.
5137 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5138 reportParseError("unexpected token, expected end of statement");
5142 return false; // parseDirectiveModule has finished successfully.
5143 } else if (Option == "nooddspreg") {
5145 Error(L, "'.module nooddspreg' requires the O32 ABI");
5149 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5151 // Synchronize the abiflags information with the FeatureBits information we
5153 getTargetStreamer().updateABIInfo(*this);
5155 // If printing assembly, use the recently updated abiflags information.
5156 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5157 // emitted at the end).
5158 getTargetStreamer().emitDirectiveModuleOddSPReg();
5160 // If this is not the end of the statement, report an error.
5161 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5162 reportParseError("unexpected token, expected end of statement");
5166 return false; // parseDirectiveModule has finished successfully.
5167 } else if (Option == "fp") {
5168 return parseDirectiveModuleFP();
5169 } else if (Option == "softfloat") {
5170 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5172 // Synchronize the ABI Flags information with the FeatureBits information we
5174 getTargetStreamer().updateABIInfo(*this);
5176 // If printing assembly, use the recently updated ABI Flags information.
5177 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5179 getTargetStreamer().emitDirectiveModuleSoftFloat();
5181 // If this is not the end of the statement, report an error.
5182 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5183 reportParseError("unexpected token, expected end of statement");
5187 return false; // parseDirectiveModule has finished successfully.
5188 } else if (Option == "hardfloat") {
5189 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5191 // Synchronize the ABI Flags information with the FeatureBits information we
5193 getTargetStreamer().updateABIInfo(*this);
5195 // If printing assembly, use the recently updated ABI Flags information.
5196 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5198 getTargetStreamer().emitDirectiveModuleHardFloat();
5200 // If this is not the end of the statement, report an error.
5201 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5202 reportParseError("unexpected token, expected end of statement");
5206 return false; // parseDirectiveModule has finished successfully.
5208 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5212 /// parseDirectiveModuleFP
5216 bool MipsAsmParser::parseDirectiveModuleFP() {
5217 MCAsmParser &Parser = getParser();
5218 MCAsmLexer &Lexer = getLexer();
5220 if (Lexer.isNot(AsmToken::Equal)) {
5221 reportParseError("unexpected token, expected equals sign '='");
5224 Parser.Lex(); // Eat '=' token.
5226 MipsABIFlagsSection::FpABIKind FpABI;
5227 if (!parseFpABIValue(FpABI, ".module"))
5230 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5231 reportParseError("unexpected token, expected end of statement");
5235 // Synchronize the abiflags information with the FeatureBits information we
5237 getTargetStreamer().updateABIInfo(*this);
5239 // If printing assembly, use the recently updated abiflags information.
5240 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5241 // emitted at the end).
5242 getTargetStreamer().emitDirectiveModuleFP();
5244 Parser.Lex(); // Consume the EndOfStatement.
5248 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5249 StringRef Directive) {
5250 MCAsmParser &Parser = getParser();
5251 MCAsmLexer &Lexer = getLexer();
5252 bool ModuleLevelOptions = Directive == ".module";
5254 if (Lexer.is(AsmToken::Identifier)) {
5255 StringRef Value = Parser.getTok().getString();
5258 if (Value != "xx") {
5259 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5264 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5268 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5269 if (ModuleLevelOptions) {
5270 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5271 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5273 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5274 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5279 if (Lexer.is(AsmToken::Integer)) {
5280 unsigned Value = Parser.getTok().getIntVal();
5283 if (Value != 32 && Value != 64) {
5284 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5290 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5294 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5295 if (ModuleLevelOptions) {
5296 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5297 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5299 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5300 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5303 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5304 if (ModuleLevelOptions) {
5305 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5306 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5308 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5309 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5319 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5320 MCAsmParser &Parser = getParser();
5321 StringRef IDVal = DirectiveID.getString();
5323 if (IDVal == ".cpload")
5324 return parseDirectiveCpLoad(DirectiveID.getLoc());
5325 if (IDVal == ".dword") {
5326 parseDataDirective(8, DirectiveID.getLoc());
5329 if (IDVal == ".ent") {
5330 StringRef SymbolName;
5332 if (Parser.parseIdentifier(SymbolName)) {
5333 reportParseError("expected identifier after .ent");
5337 // There's an undocumented extension that allows an integer to
5338 // follow the name of the procedure which AFAICS is ignored by GAS.
5339 // Example: .ent foo,2
5340 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5341 if (getLexer().isNot(AsmToken::Comma)) {
5342 // Even though we accept this undocumented extension for compatibility
5343 // reasons, the additional integer argument does not actually change
5344 // the behaviour of the '.ent' directive, so we would like to discourage
5345 // its use. We do this by not referring to the extended version in
5346 // error messages which are not directly related to its use.
5347 reportParseError("unexpected token, expected end of statement");
5350 Parser.Lex(); // Eat the comma.
5351 const MCExpr *DummyNumber;
5352 int64_t DummyNumberVal;
5353 // If the user was explicitly trying to use the extended version,
5354 // we still give helpful extension-related error messages.
5355 if (Parser.parseExpression(DummyNumber)) {
5356 reportParseError("expected number after comma");
5359 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5360 reportParseError("expected an absolute expression after comma");
5365 // If this is not the end of the statement, report an error.
5366 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5367 reportParseError("unexpected token, expected end of statement");
5371 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5373 getTargetStreamer().emitDirectiveEnt(*Sym);
5378 if (IDVal == ".end") {
5379 StringRef SymbolName;
5381 if (Parser.parseIdentifier(SymbolName)) {
5382 reportParseError("expected identifier after .end");
5386 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5387 reportParseError("unexpected token, expected end of statement");
5391 if (CurrentFn == nullptr) {
5392 reportParseError(".end used without .ent");
5396 if ((SymbolName != CurrentFn->getName())) {
5397 reportParseError(".end symbol does not match .ent symbol");
5401 getTargetStreamer().emitDirectiveEnd(SymbolName);
5402 CurrentFn = nullptr;
5406 if (IDVal == ".frame") {
5407 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5408 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5409 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5410 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5411 reportParseError("expected stack register");
5415 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5416 if (!StackRegOpnd.isGPRAsmReg()) {
5417 reportParseError(StackRegOpnd.getStartLoc(),
5418 "expected general purpose register");
5421 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5423 if (Parser.getTok().is(AsmToken::Comma))
5426 reportParseError("unexpected token, expected comma");
5430 // Parse the frame size.
5431 const MCExpr *FrameSize;
5432 int64_t FrameSizeVal;
5434 if (Parser.parseExpression(FrameSize)) {
5435 reportParseError("expected frame size value");
5439 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5440 reportParseError("frame size not an absolute expression");
5444 if (Parser.getTok().is(AsmToken::Comma))
5447 reportParseError("unexpected token, expected comma");
5451 // Parse the return register.
5453 ResTy = parseAnyRegister(TmpReg);
5454 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5455 reportParseError("expected return register");
5459 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5460 if (!ReturnRegOpnd.isGPRAsmReg()) {
5461 reportParseError(ReturnRegOpnd.getStartLoc(),
5462 "expected general purpose register");
5466 // If this is not the end of the statement, report an error.
5467 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5468 reportParseError("unexpected token, expected end of statement");
5472 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5473 ReturnRegOpnd.getGPR32Reg());
5477 if (IDVal == ".set") {
5478 return parseDirectiveSet();
5481 if (IDVal == ".mask" || IDVal == ".fmask") {
5482 // .mask bitmask, frame_offset
5483 // bitmask: One bit for each register used.
5484 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5485 // first register is expected to be saved.
5487 // .mask 0x80000000, -4
5488 // .fmask 0x80000000, -4
5491 // Parse the bitmask
5492 const MCExpr *BitMask;
5495 if (Parser.parseExpression(BitMask)) {
5496 reportParseError("expected bitmask value");
5500 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5501 reportParseError("bitmask not an absolute expression");
5505 if (Parser.getTok().is(AsmToken::Comma))
5508 reportParseError("unexpected token, expected comma");
5512 // Parse the frame_offset
5513 const MCExpr *FrameOffset;
5514 int64_t FrameOffsetVal;
5516 if (Parser.parseExpression(FrameOffset)) {
5517 reportParseError("expected frame offset value");
5521 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5522 reportParseError("frame offset not an absolute expression");
5526 // If this is not the end of the statement, report an error.
5527 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5528 reportParseError("unexpected token, expected end of statement");
5532 if (IDVal == ".mask")
5533 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5535 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5539 if (IDVal == ".nan")
5540 return parseDirectiveNaN();
5542 if (IDVal == ".gpword") {
5543 parseDirectiveGpWord();
5547 if (IDVal == ".gpdword") {
5548 parseDirectiveGpDWord();
5552 if (IDVal == ".word") {
5553 parseDataDirective(4, DirectiveID.getLoc());
5557 if (IDVal == ".option")
5558 return parseDirectiveOption();
5560 if (IDVal == ".abicalls") {
5561 getTargetStreamer().emitDirectiveAbiCalls();
5562 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5563 Error(Parser.getTok().getLoc(),
5564 "unexpected token, expected end of statement");
5566 Parser.eatToEndOfStatement();
5571 if (IDVal == ".cpsetup")
5572 return parseDirectiveCPSetup();
5574 if (IDVal == ".module")
5575 return parseDirectiveModule();
5577 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5578 return parseInternalDirectiveReallowModule();
5580 if (IDVal == ".insn")
5581 return parseInsnDirective();
5586 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5587 // If this is not the end of the statement, report an error.
5588 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5589 reportParseError("unexpected token, expected end of statement");
5593 getTargetStreamer().reallowModuleDirective();
5595 getParser().Lex(); // Eat EndOfStatement token.
5599 extern "C" void LLVMInitializeMipsAsmParser() {
5600 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5601 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5602 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5603 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5606 #define GET_REGISTER_MATCHER
5607 #define GET_MATCHER_IMPLEMENTATION
5608 #include "MipsGenAsmMatcher.inc"