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");
1740 Opnd = Inst.getOperand(2);
1742 return Error(IDLoc, "expected immediate operand kind");
1743 Imm = Opnd.getImm();
1744 if (Imm < 0 || Imm > 15)
1745 return Error(IDLoc, "immediate operand value out of range");
1747 case Mips::LHU16_MM:
1749 Opnd = Inst.getOperand(2);
1751 return Error(IDLoc, "expected immediate operand kind");
1752 Imm = Opnd.getImm();
1753 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1754 return Error(IDLoc, "immediate operand value out of range");
1758 Opnd = Inst.getOperand(2);
1760 return Error(IDLoc, "expected immediate operand kind");
1761 Imm = Opnd.getImm();
1762 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1763 return Error(IDLoc, "immediate operand value out of range");
1765 case Mips::PREFX_MM:
1768 Opnd = Inst.getOperand(2);
1770 return Error(IDLoc, "expected immediate operand kind");
1771 Imm = Opnd.getImm();
1772 if (!isUInt<5>(Imm))
1773 return Error(IDLoc, "immediate operand value out of range");
1775 case Mips::ADDIUPC_MM:
1776 MCOperand Opnd = Inst.getOperand(1);
1778 return Error(IDLoc, "expected immediate operand kind");
1779 int Imm = Opnd.getImm();
1780 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1781 return Error(IDLoc, "immediate operand value out of range");
1786 if (needsExpansion(Inst)) {
1787 if (expandInstruction(Inst, IDLoc, Instructions))
1790 Instructions.push_back(Inst);
1792 // If this instruction has a delay slot and .set reorder is active,
1793 // emit a NOP after it.
1794 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1795 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1800 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1802 switch (Inst.getOpcode()) {
1803 case Mips::LoadImm32:
1804 case Mips::LoadImm64:
1805 case Mips::LoadAddrImm32:
1806 case Mips::LoadAddrImm64:
1807 case Mips::LoadAddrReg32:
1808 case Mips::LoadAddrReg64:
1809 case Mips::B_MM_Pseudo:
1810 case Mips::B_MMR6_Pseudo:
1813 case Mips::JalOneReg:
1814 case Mips::JalTwoReg:
1833 case Mips::SDivMacro:
1834 case Mips::UDivMacro:
1835 case Mips::DSDivMacro:
1836 case Mips::DUDivMacro:
1845 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1846 SmallVectorImpl<MCInst> &Instructions) {
1847 switch (Inst.getOpcode()) {
1848 default: llvm_unreachable("unimplemented expansion");
1849 case Mips::LoadImm32:
1850 return expandLoadImm(Inst, true, IDLoc, Instructions);
1851 case Mips::LoadImm64:
1852 return expandLoadImm(Inst, false, IDLoc, Instructions);
1853 case Mips::LoadAddrImm32:
1854 case Mips::LoadAddrImm64:
1855 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1856 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1857 "expected immediate operand kind");
1859 return expandLoadAddress(
1860 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1861 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1862 case Mips::LoadAddrReg32:
1863 case Mips::LoadAddrReg64:
1864 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1865 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1866 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1867 "expected immediate operand kind");
1869 return expandLoadAddress(
1870 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1871 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1872 case Mips::B_MM_Pseudo:
1873 case Mips::B_MMR6_Pseudo:
1874 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1877 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1878 case Mips::JalOneReg:
1879 case Mips::JalTwoReg:
1880 return expandJalWithRegs(Inst, IDLoc, Instructions);
1883 return expandBranchImm(Inst, IDLoc, Instructions);
1900 return expandCondBranches(Inst, IDLoc, Instructions);
1901 case Mips::SDivMacro:
1902 return expandDiv(Inst, IDLoc, Instructions, false, true);
1903 case Mips::DSDivMacro:
1904 return expandDiv(Inst, IDLoc, Instructions, true, true);
1905 case Mips::UDivMacro:
1906 return expandDiv(Inst, IDLoc, Instructions, false, false);
1907 case Mips::DUDivMacro:
1908 return expandDiv(Inst, IDLoc, Instructions, true, false);
1910 return expandUlhu(Inst, IDLoc, Instructions);
1912 return expandUlw(Inst, IDLoc, Instructions);
1917 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1918 SmallVectorImpl<MCInst> &Instructions) {
1920 tmpInst.setOpcode(Opcode);
1921 tmpInst.addOperand(MCOperand::createReg(Reg0));
1922 tmpInst.addOperand(Op1);
1923 tmpInst.setLoc(IDLoc);
1924 Instructions.push_back(tmpInst);
1927 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1928 SmallVectorImpl<MCInst> &Instructions) {
1929 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1932 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1933 SmallVectorImpl<MCInst> &Instructions) {
1934 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1937 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1938 SmallVectorImpl<MCInst> &Instructions) {
1940 tmpInst.setOpcode(Opcode);
1941 tmpInst.addOperand(MCOperand::createImm(Imm1));
1942 tmpInst.addOperand(MCOperand::createImm(Imm2));
1943 tmpInst.setLoc(IDLoc);
1944 Instructions.push_back(tmpInst);
1947 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1948 SmallVectorImpl<MCInst> &Instructions) {
1950 tmpInst.setOpcode(Opcode);
1951 tmpInst.addOperand(MCOperand::createReg(Reg0));
1952 tmpInst.setLoc(IDLoc);
1953 Instructions.push_back(tmpInst);
1956 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1957 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1959 tmpInst.setOpcode(Opcode);
1960 tmpInst.addOperand(MCOperand::createReg(Reg0));
1961 tmpInst.addOperand(MCOperand::createReg(Reg1));
1962 tmpInst.addOperand(Op2);
1963 tmpInst.setLoc(IDLoc);
1964 Instructions.push_back(tmpInst);
1967 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1968 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1969 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1973 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1974 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1975 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1979 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1980 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1981 if (ShiftAmount >= 32) {
1982 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1987 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1989 } // end anonymous namespace.
1991 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1992 SmallVectorImpl<MCInst> &Instructions) {
1993 // Create a JALR instruction which is going to replace the pseudo-JAL.
1995 JalrInst.setLoc(IDLoc);
1996 const MCOperand FirstRegOp = Inst.getOperand(0);
1997 const unsigned Opcode = Inst.getOpcode();
1999 if (Opcode == Mips::JalOneReg) {
2000 // jal $rs => jalr $rs
2001 if (inMicroMipsMode()) {
2002 JalrInst.setOpcode(Mips::JALR16_MM);
2003 JalrInst.addOperand(FirstRegOp);
2005 JalrInst.setOpcode(Mips::JALR);
2006 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2007 JalrInst.addOperand(FirstRegOp);
2009 } else if (Opcode == Mips::JalTwoReg) {
2010 // jal $rd, $rs => jalr $rd, $rs
2011 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2012 JalrInst.addOperand(FirstRegOp);
2013 const MCOperand SecondRegOp = Inst.getOperand(1);
2014 JalrInst.addOperand(SecondRegOp);
2016 Instructions.push_back(JalrInst);
2018 // If .set reorder is active, emit a NOP after it.
2019 if (AssemblerOptions.back()->isReorder()) {
2020 // This is a 32-bit NOP because these 2 pseudo-instructions
2021 // do not have a short delay slot.
2023 NopInst.setOpcode(Mips::SLL);
2024 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2025 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2026 NopInst.addOperand(MCOperand::createImm(0));
2027 Instructions.push_back(NopInst);
2033 /// Can the value be represented by a unsigned N-bit value and a shift left?
2034 template<unsigned N>
2035 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2036 unsigned BitNum = findFirstSet(x);
2038 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2041 /// Load (or add) an immediate into a register.
2043 /// @param ImmValue The immediate to load.
2044 /// @param DstReg The register that will hold the immediate.
2045 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2046 /// for a simple initialization.
2047 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2048 /// @param IsAddress True if the immediate represents an address. False if it
2050 /// @param IDLoc Location of the immediate in the source file.
2051 /// @param Instructions The instructions emitted by this expansion.
2052 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2053 unsigned SrcReg, bool Is32BitImm,
2054 bool IsAddress, SMLoc IDLoc,
2055 SmallVectorImpl<MCInst> &Instructions) {
2056 if (!Is32BitImm && !isGP64bit()) {
2057 Error(IDLoc, "instruction requires a 64-bit architecture");
2062 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2063 // Sign extend up to 64-bit so that the predicates match the hardware
2064 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2066 ImmValue = SignExtend64<32>(ImmValue);
2068 Error(IDLoc, "instruction requires a 32-bit immediate");
2073 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2074 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2076 bool UseSrcReg = false;
2077 if (SrcReg != Mips::NoRegister)
2080 unsigned TmpReg = DstReg;
2081 if (UseSrcReg && (DstReg == SrcReg)) {
2082 // At this point we need AT to perform the expansions and we exit if it is
2084 unsigned ATReg = getATReg(IDLoc);
2090 if (isInt<16>(ImmValue)) {
2094 // This doesn't quite follow the usual ABI expectations for N32 but matches
2095 // traditional assembler behaviour. N32 would normally use addiu for both
2096 // integers and addresses.
2097 if (IsAddress && !Is32BitImm) {
2098 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2102 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2106 if (isUInt<16>(ImmValue)) {
2107 unsigned TmpReg = DstReg;
2108 if (SrcReg == DstReg) {
2109 TmpReg = getATReg(IDLoc);
2114 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2116 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2120 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2121 warnIfNoMacro(IDLoc);
2123 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2124 uint16_t Bits15To0 = ImmValue & 0xffff;
2126 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2127 // Traditional behaviour seems to special case this particular value. It's
2128 // not clear why other masks are handled differently.
2129 if (ImmValue == 0xffffffff) {
2130 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2131 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2133 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2137 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2139 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2140 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2142 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2144 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2148 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2150 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2152 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2156 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2158 Error(IDLoc, "instruction requires a 32-bit immediate");
2162 // Traditionally, these immediates are shifted as little as possible and as
2163 // such we align the most significant bit to bit 15 of our temporary.
2164 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2165 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2166 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2167 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2168 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2169 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2172 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2177 warnIfNoMacro(IDLoc);
2179 // The remaining case is packed with a sequence of dsll and ori with zeros
2180 // being omitted and any neighbouring dsll's being coalesced.
2181 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2183 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2184 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2185 IDLoc, Instructions))
2188 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2189 // skip it and defer the shift to the next chunk.
2190 unsigned ShiftCarriedForwards = 16;
2191 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2192 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2194 if (ImmChunk != 0) {
2195 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2197 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2198 ShiftCarriedForwards = 0;
2201 ShiftCarriedForwards += 16;
2203 ShiftCarriedForwards -= 16;
2205 // Finish any remaining shifts left by trailing zeros.
2206 if (ShiftCarriedForwards)
2207 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2211 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2216 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2217 SmallVectorImpl<MCInst> &Instructions) {
2218 const MCOperand &ImmOp = Inst.getOperand(1);
2219 assert(ImmOp.isImm() && "expected immediate operand kind");
2220 const MCOperand &DstRegOp = Inst.getOperand(0);
2221 assert(DstRegOp.isReg() && "expected register operand kind");
2223 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2224 Is32BitImm, false, IDLoc, Instructions))
2230 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2231 const MCOperand &Offset,
2232 bool Is32BitAddress, SMLoc IDLoc,
2233 SmallVectorImpl<MCInst> &Instructions) {
2234 // la can't produce a usable address when addresses are 64-bit.
2235 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2236 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2237 // We currently can't do this because we depend on the equality
2238 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2239 Error(IDLoc, "la used to load 64-bit address");
2240 // Continue as if we had 'dla' instead.
2241 Is32BitAddress = false;
2244 // dla requires 64-bit addresses.
2245 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2246 Error(IDLoc, "instruction requires a 64-bit architecture");
2250 if (!Offset.isImm())
2251 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2252 Is32BitAddress, IDLoc, Instructions);
2254 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2255 IDLoc, Instructions);
2258 bool MipsAsmParser::loadAndAddSymbolAddress(
2259 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2260 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2261 warnIfNoMacro(IDLoc);
2263 // FIXME: The way we're handling symbols right now prevents simple expressions
2264 // like foo+8. We'll be able to fix this once our unary operators (%hi
2265 // and similar) are treated as operators rather than as fixup types.
2266 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2267 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2268 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2269 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2270 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2272 bool UseSrcReg = SrcReg != Mips::NoRegister;
2274 // This is the 64-bit symbol address expansion.
2275 if (ABI.ArePtrs64bit() && isGP64bit()) {
2276 // We always need AT for the 64-bit expansion.
2277 // If it is not available we exit.
2278 unsigned ATReg = getATReg(IDLoc);
2282 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2283 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2284 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2285 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2287 if (UseSrcReg && (DstReg == SrcReg)) {
2288 // If $rs is the same as $rd:
2289 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2290 // daddiu $at, $at, %higher(sym)
2291 // dsll $at, $at, 16
2292 // daddiu $at, $at, %hi(sym)
2293 // dsll $at, $at, 16
2294 // daddiu $at, $at, %lo(sym)
2295 // daddu $rd, $at, $rd
2296 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2298 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2299 IDLoc, Instructions);
2300 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2301 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2303 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2304 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2306 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2311 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2312 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2313 // lui $at, %hi(sym)
2314 // daddiu $rd, $rd, %higher(sym)
2315 // daddiu $at, $at, %lo(sym)
2316 // dsll32 $rd, $rd, 0
2317 // daddu $rd, $rd, $at
2318 // (daddu $rd, $rd, $rs)
2319 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2321 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2323 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2324 IDLoc, Instructions);
2325 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2327 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2328 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2330 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2335 // And now, the 32-bit symbol address expansion:
2336 // If $rs is the same as $rd:
2337 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2338 // ori $at, $at, %lo(sym)
2339 // addu $rd, $at, $rd
2340 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2341 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2342 // ori $rd, $rd, %lo(sym)
2343 // (addu $rd, $rd, $rs)
2344 unsigned TmpReg = DstReg;
2345 if (UseSrcReg && (DstReg == SrcReg)) {
2346 // If $rs is the same as $rd, we need to use AT.
2347 // If it is not available we exit.
2348 unsigned ATReg = getATReg(IDLoc);
2354 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2355 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2359 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2361 assert(DstReg == TmpReg);
2366 bool MipsAsmParser::expandUncondBranchMMPseudo(
2367 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2368 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2369 "unexpected number of operands");
2371 MCOperand Offset = Inst.getOperand(0);
2372 if (Offset.isExpr()) {
2374 Inst.setOpcode(Mips::BEQ_MM);
2375 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2376 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2377 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2379 assert(Offset.isImm() && "expected immediate operand kind");
2380 if (isIntN(11, Offset.getImm())) {
2381 // If offset fits into 11 bits then this instruction becomes microMIPS
2382 // 16-bit unconditional branch instruction.
2383 if (inMicroMipsMode())
2384 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2386 if (!isIntN(17, Offset.getImm()))
2387 Error(IDLoc, "branch target out of range");
2388 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2389 Error(IDLoc, "branch to misaligned address");
2391 Inst.setOpcode(Mips::BEQ_MM);
2392 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2393 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2394 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2397 Instructions.push_back(Inst);
2399 // If .set reorder is active and branch instruction has a delay slot,
2400 // emit a NOP after it.
2401 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2402 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2403 createNop(true, IDLoc, Instructions);
2408 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2409 SmallVectorImpl<MCInst> &Instructions) {
2410 const MCOperand &DstRegOp = Inst.getOperand(0);
2411 assert(DstRegOp.isReg() && "expected register operand kind");
2413 const MCOperand &ImmOp = Inst.getOperand(1);
2414 assert(ImmOp.isImm() && "expected immediate operand kind");
2416 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2417 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2419 unsigned OpCode = 0;
2420 switch(Inst.getOpcode()) {
2428 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2432 int64_t ImmValue = ImmOp.getImm();
2433 if (ImmValue == 0) {
2435 BranchInst.setOpcode(OpCode);
2436 BranchInst.addOperand(DstRegOp);
2437 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2438 BranchInst.addOperand(MemOffsetOp);
2439 Instructions.push_back(BranchInst);
2441 warnIfNoMacro(IDLoc);
2443 unsigned ATReg = getATReg(IDLoc);
2447 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2448 IDLoc, Instructions))
2452 BranchInst.setOpcode(OpCode);
2453 BranchInst.addOperand(DstRegOp);
2454 BranchInst.addOperand(MCOperand::createReg(ATReg));
2455 BranchInst.addOperand(MemOffsetOp);
2456 Instructions.push_back(BranchInst);
2461 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2462 SmallVectorImpl<MCInst> &Instructions,
2463 bool isLoad, bool isImmOpnd) {
2465 unsigned ImmOffset, HiOffset, LoOffset;
2466 const MCExpr *ExprOffset;
2468 // 1st operand is either the source or destination register.
2469 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2470 unsigned RegOpNum = Inst.getOperand(0).getReg();
2471 // 2nd operand is the base register.
2472 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2473 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2474 // 3rd operand is either an immediate or expression.
2476 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2477 ImmOffset = Inst.getOperand(2).getImm();
2478 LoOffset = ImmOffset & 0x0000ffff;
2479 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2480 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2481 if (LoOffset & 0x8000)
2484 ExprOffset = Inst.getOperand(2).getExpr();
2485 // All instructions will have the same location.
2486 TempInst.setLoc(IDLoc);
2487 // These are some of the types of expansions we perform here:
2488 // 1) lw $8, sym => lui $8, %hi(sym)
2489 // lw $8, %lo(sym)($8)
2490 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2492 // lw $8, %lo(offset)($9)
2493 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2495 // lw $8, %lo(offset)($at)
2496 // 4) sw $8, sym => lui $at, %hi(sym)
2497 // sw $8, %lo(sym)($at)
2498 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2500 // sw $8, %lo(offset)($at)
2501 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2502 // ldc1 $f0, %lo(sym)($at)
2504 // For load instructions we can use the destination register as a temporary
2505 // if base and dst are different (examples 1 and 2) and if the base register
2506 // is general purpose otherwise we must use $at (example 6) and error if it's
2507 // not available. For stores we must use $at (examples 4 and 5) because we
2508 // must not clobber the source register setting up the offset.
2509 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2510 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2511 unsigned RegClassIDOp0 =
2512 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2513 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2514 (RegClassIDOp0 == Mips::GPR64RegClassID);
2515 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2516 TmpRegNum = RegOpNum;
2518 // At this point we need AT to perform the expansions and we exit if it is
2520 TmpRegNum = getATReg(IDLoc);
2525 TempInst.setOpcode(Mips::LUi);
2526 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2528 TempInst.addOperand(MCOperand::createImm(HiOffset));
2530 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2531 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2533 // Add the instruction to the list.
2534 Instructions.push_back(TempInst);
2535 // Prepare TempInst for next instruction.
2537 // Add temp register to base.
2538 if (BaseRegNum != Mips::ZERO) {
2539 TempInst.setOpcode(Mips::ADDu);
2540 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2541 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2542 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2543 Instructions.push_back(TempInst);
2546 // And finally, create original instruction with low part
2547 // of offset and new base.
2548 TempInst.setOpcode(Inst.getOpcode());
2549 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2550 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2552 TempInst.addOperand(MCOperand::createImm(LoOffset));
2554 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2555 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2557 Instructions.push_back(TempInst);
2562 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2563 SmallVectorImpl<MCInst> &Instructions) {
2564 unsigned OpNum = Inst.getNumOperands();
2565 unsigned Opcode = Inst.getOpcode();
2566 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2568 assert (Inst.getOperand(OpNum - 1).isImm() &&
2569 Inst.getOperand(OpNum - 2).isReg() &&
2570 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2572 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2573 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2574 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2575 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2576 // It can be implemented as SWM16 or LWM16 instruction.
2577 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2579 Inst.setOpcode(NewOpcode);
2580 Instructions.push_back(Inst);
2584 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2585 SmallVectorImpl<MCInst> &Instructions) {
2586 unsigned PseudoOpcode = Inst.getOpcode();
2587 unsigned SrcReg = Inst.getOperand(0).getReg();
2588 unsigned TrgReg = Inst.getOperand(1).getReg();
2589 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2591 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2592 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2594 switch (PseudoOpcode) {
2599 AcceptsEquality = false;
2600 ReverseOrderSLT = false;
2601 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2602 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2603 ZeroSrcOpcode = Mips::BGTZ;
2604 ZeroTrgOpcode = Mips::BLTZ;
2610 AcceptsEquality = true;
2611 ReverseOrderSLT = true;
2612 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2613 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2614 ZeroSrcOpcode = Mips::BGEZ;
2615 ZeroTrgOpcode = Mips::BLEZ;
2621 AcceptsEquality = true;
2622 ReverseOrderSLT = false;
2623 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2624 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2625 ZeroSrcOpcode = Mips::BLEZ;
2626 ZeroTrgOpcode = Mips::BGEZ;
2632 AcceptsEquality = false;
2633 ReverseOrderSLT = true;
2634 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2635 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2636 ZeroSrcOpcode = Mips::BLTZ;
2637 ZeroTrgOpcode = Mips::BGTZ;
2640 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2644 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2645 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2646 if (IsSrcRegZero && IsTrgRegZero) {
2647 // FIXME: All of these Opcode-specific if's are needed for compatibility
2648 // with GAS' behaviour. However, they may not generate the most efficient
2649 // code in some circumstances.
2650 if (PseudoOpcode == Mips::BLT) {
2651 BranchInst.setOpcode(Mips::BLTZ);
2652 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2653 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2654 Instructions.push_back(BranchInst);
2657 if (PseudoOpcode == Mips::BLE) {
2658 BranchInst.setOpcode(Mips::BLEZ);
2659 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2660 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2661 Instructions.push_back(BranchInst);
2662 Warning(IDLoc, "branch is always taken");
2665 if (PseudoOpcode == Mips::BGE) {
2666 BranchInst.setOpcode(Mips::BGEZ);
2667 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2668 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2669 Instructions.push_back(BranchInst);
2670 Warning(IDLoc, "branch is always taken");
2673 if (PseudoOpcode == Mips::BGT) {
2674 BranchInst.setOpcode(Mips::BGTZ);
2675 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2676 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2677 Instructions.push_back(BranchInst);
2680 if (PseudoOpcode == Mips::BGTU) {
2681 BranchInst.setOpcode(Mips::BNE);
2682 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2683 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2684 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2685 Instructions.push_back(BranchInst);
2688 if (AcceptsEquality) {
2689 // If both registers are $0 and the pseudo-branch accepts equality, it
2690 // will always be taken, so we emit an unconditional branch.
2691 BranchInst.setOpcode(Mips::BEQ);
2692 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2693 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2694 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2695 Instructions.push_back(BranchInst);
2696 Warning(IDLoc, "branch is always taken");
2699 // If both registers are $0 and the pseudo-branch does not accept
2700 // equality, it will never be taken, so we don't have to emit anything.
2703 if (IsSrcRegZero || IsTrgRegZero) {
2704 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2705 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2706 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2707 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2708 // the pseudo-branch will never be taken, so we don't emit anything.
2709 // This only applies to unsigned pseudo-branches.
2712 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2713 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2714 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2715 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2716 // the pseudo-branch will always be taken, so we emit an unconditional
2718 // This only applies to unsigned pseudo-branches.
2719 BranchInst.setOpcode(Mips::BEQ);
2720 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2721 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2722 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2723 Instructions.push_back(BranchInst);
2724 Warning(IDLoc, "branch is always taken");
2728 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2729 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2730 // the pseudo-branch will be taken only when the non-zero register is
2731 // different from 0, so we emit a BNEZ.
2733 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2734 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2735 // the pseudo-branch will be taken only when the non-zero register is
2736 // equal to 0, so we emit a BEQZ.
2738 // Because only BLEU and BGEU branch on equality, we can use the
2739 // AcceptsEquality variable to decide when to emit the BEQZ.
2740 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2741 BranchInst.addOperand(
2742 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2743 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2744 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2745 Instructions.push_back(BranchInst);
2748 // If we have a signed pseudo-branch and one of the registers is $0,
2749 // we can use an appropriate compare-to-zero branch. We select which one
2750 // to use in the switch statement above.
2751 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2752 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2753 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2754 Instructions.push_back(BranchInst);
2758 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2759 // expansions. If it is not available, we return.
2760 unsigned ATRegNum = getATReg(IDLoc);
2764 warnIfNoMacro(IDLoc);
2766 // SLT fits well with 2 of our 4 pseudo-branches:
2767 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2768 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2769 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2770 // This is accomplished by using a BNEZ with the result of the SLT.
2772 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2773 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2774 // Because only BGE and BLE branch on equality, we can use the
2775 // AcceptsEquality variable to decide when to emit the BEQZ.
2776 // Note that the order of the SLT arguments doesn't change between
2779 // The same applies to the unsigned variants, except that SLTu is used
2782 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2783 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2784 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2785 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2786 Instructions.push_back(SetInst);
2789 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2791 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQL : Mips::BNEL);
2792 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2793 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2794 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2795 Instructions.push_back(BranchInst);
2799 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2800 SmallVectorImpl<MCInst> &Instructions,
2801 const bool IsMips64, const bool Signed) {
2802 if (hasMips32r6()) {
2803 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2807 warnIfNoMacro(IDLoc);
2809 const MCOperand &RsRegOp = Inst.getOperand(0);
2810 assert(RsRegOp.isReg() && "expected register operand kind");
2811 unsigned RsReg = RsRegOp.getReg();
2813 const MCOperand &RtRegOp = Inst.getOperand(1);
2814 assert(RtRegOp.isReg() && "expected register operand kind");
2815 unsigned RtReg = RtRegOp.getReg();
2820 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2821 ZeroReg = Mips::ZERO_64;
2823 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2824 ZeroReg = Mips::ZERO;
2827 bool UseTraps = useTraps();
2829 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2830 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2831 Warning(IDLoc, "dividing zero by zero");
2833 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2835 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2839 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2843 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2848 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2849 Warning(IDLoc, "division by zero");
2852 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2856 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2861 // FIXME: The values for these two BranchTarget variables may be different in
2862 // micromips. These magic numbers need to be removed.
2863 unsigned BranchTargetNoTraps;
2864 unsigned BranchTarget;
2867 BranchTarget = IsMips64 ? 12 : 8;
2868 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2870 BranchTarget = IsMips64 ? 20 : 16;
2871 BranchTargetNoTraps = 8;
2872 // Branch to the li instruction.
2873 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2877 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2880 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2883 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2887 unsigned ATReg = getATReg(IDLoc);
2891 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2893 // Branch to the mflo instruction.
2894 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2895 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2896 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2898 // Branch to the mflo instruction.
2899 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2900 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2904 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2906 // Branch to the mflo instruction.
2907 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2908 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2909 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2911 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2915 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2916 SmallVectorImpl<MCInst> &Instructions) {
2917 if (hasMips32r6() || hasMips64r6()) {
2918 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2922 warnIfNoMacro(IDLoc);
2924 const MCOperand &DstRegOp = Inst.getOperand(0);
2925 assert(DstRegOp.isReg() && "expected register operand kind");
2927 const MCOperand &SrcRegOp = Inst.getOperand(1);
2928 assert(SrcRegOp.isReg() && "expected register operand kind");
2930 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2931 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2933 unsigned DstReg = DstRegOp.getReg();
2934 unsigned SrcReg = SrcRegOp.getReg();
2935 int64_t OffsetValue = OffsetImmOp.getImm();
2937 // NOTE: We always need AT for ULHU, as it is always used as the source
2938 // register for one of the LBu's.
2939 unsigned ATReg = getATReg(IDLoc);
2943 // When the value of offset+1 does not fit in 16 bits, we have to load the
2944 // offset in AT, (D)ADDu the original source register (if there was one), and
2945 // then use AT as the source register for the 2 generated LBu's.
2946 bool LoadedOffsetInAT = false;
2947 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2948 LoadedOffsetInAT = true;
2950 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2951 true, IDLoc, Instructions))
2954 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2955 // because it will make our output more similar to GAS'. For example,
2956 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2957 // instead of just an "ori $1, $9, 32768".
2958 // NOTE: If there is no source register specified in the ULHU, the parser
2959 // will interpret it as $0.
2960 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2961 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2964 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2965 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2966 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2968 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2970 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2971 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2973 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2974 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2977 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2980 TmpInst.setOpcode(Mips::LBu);
2981 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2982 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2983 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2984 Instructions.push_back(TmpInst);
2987 TmpInst.setOpcode(Mips::LBu);
2988 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2989 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2990 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2991 Instructions.push_back(TmpInst);
2994 TmpInst.setOpcode(Mips::SLL);
2995 TmpInst.addOperand(MCOperand::createReg(SllReg));
2996 TmpInst.addOperand(MCOperand::createReg(SllReg));
2997 TmpInst.addOperand(MCOperand::createImm(8));
2998 Instructions.push_back(TmpInst);
3001 TmpInst.setOpcode(Mips::OR);
3002 TmpInst.addOperand(MCOperand::createReg(DstReg));
3003 TmpInst.addOperand(MCOperand::createReg(DstReg));
3004 TmpInst.addOperand(MCOperand::createReg(ATReg));
3005 Instructions.push_back(TmpInst);
3010 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3011 SmallVectorImpl<MCInst> &Instructions) {
3012 if (hasMips32r6() || hasMips64r6()) {
3013 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3017 const MCOperand &DstRegOp = Inst.getOperand(0);
3018 assert(DstRegOp.isReg() && "expected register operand kind");
3020 const MCOperand &SrcRegOp = Inst.getOperand(1);
3021 assert(SrcRegOp.isReg() && "expected register operand kind");
3023 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3024 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3026 unsigned SrcReg = SrcRegOp.getReg();
3027 int64_t OffsetValue = OffsetImmOp.getImm();
3030 // When the value of offset+3 does not fit in 16 bits, we have to load the
3031 // offset in AT, (D)ADDu the original source register (if there was one), and
3032 // then use AT as the source register for the generated LWL and LWR.
3033 bool LoadedOffsetInAT = false;
3034 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3035 ATReg = getATReg(IDLoc);
3038 LoadedOffsetInAT = true;
3040 warnIfNoMacro(IDLoc);
3042 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3043 true, IDLoc, Instructions))
3046 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3047 // because it will make our output more similar to GAS'. For example,
3048 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3049 // instead of just an "ori $1, $9, 32768".
3050 // NOTE: If there is no source register specified in the ULW, the parser
3051 // will interpret it as $0.
3052 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3053 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3056 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3057 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3059 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3060 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3062 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3063 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3066 MCInst LeftLoadInst;
3067 LeftLoadInst.setOpcode(Mips::LWL);
3068 LeftLoadInst.addOperand(DstRegOp);
3069 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3070 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3071 Instructions.push_back(LeftLoadInst);
3073 MCInst RightLoadInst;
3074 RightLoadInst.setOpcode(Mips::LWR);
3075 RightLoadInst.addOperand(DstRegOp);
3076 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3077 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3078 Instructions.push_back(RightLoadInst);
3083 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3084 SmallVectorImpl<MCInst> &Instructions) {
3086 if (hasShortDelaySlot) {
3087 NopInst.setOpcode(Mips::MOVE16_MM);
3088 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3089 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3091 NopInst.setOpcode(Mips::SLL);
3092 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3093 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3094 NopInst.addOperand(MCOperand::createImm(0));
3096 Instructions.push_back(NopInst);
3099 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3100 unsigned TrgReg, bool Is64Bit,
3101 SmallVectorImpl<MCInst> &Instructions) {
3102 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3106 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3107 // As described by the Mips32r2 spec, the registers Rd and Rs for
3108 // jalr.hb must be different.
3109 unsigned Opcode = Inst.getOpcode();
3111 if (Opcode == Mips::JALR_HB &&
3112 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3113 return Match_RequiresDifferentSrcAndDst;
3115 return Match_Success;
3118 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3119 OperandVector &Operands,
3121 uint64_t &ErrorInfo,
3122 bool MatchingInlineAsm) {
3125 SmallVector<MCInst, 8> Instructions;
3126 unsigned MatchResult =
3127 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3129 switch (MatchResult) {
3130 case Match_Success: {
3131 if (processInstruction(Inst, IDLoc, Instructions))
3133 for (unsigned i = 0; i < Instructions.size(); i++)
3134 Out.EmitInstruction(Instructions[i], STI);
3137 case Match_MissingFeature:
3138 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3140 case Match_InvalidOperand: {
3141 SMLoc ErrorLoc = IDLoc;
3142 if (ErrorInfo != ~0ULL) {
3143 if (ErrorInfo >= Operands.size())
3144 return Error(IDLoc, "too few operands for instruction");
3146 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3147 if (ErrorLoc == SMLoc())
3151 return Error(ErrorLoc, "invalid operand for instruction");
3153 case Match_MnemonicFail:
3154 return Error(IDLoc, "invalid instruction");
3155 case Match_RequiresDifferentSrcAndDst:
3156 return Error(IDLoc, "source and destination must be different");
3159 llvm_unreachable("Implement any new match types added!");
3162 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3163 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3164 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3165 ") without \".set noat\"");
3168 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3169 if (!AssemblerOptions.back()->isMacro())
3170 Warning(Loc, "macro instruction expanded into multiple instructions");
3174 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3175 SMRange Range, bool ShowColors) {
3176 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3177 Range, SMFixIt(Range, FixMsg),
3181 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3184 CC = StringSwitch<unsigned>(Name)
3220 if (!(isABI_N32() || isABI_N64()))
3223 if (12 <= CC && CC <= 15) {
3224 // Name is one of t4-t7
3225 AsmToken RegTok = getLexer().peekTok();
3226 SMRange RegRange = RegTok.getLocRange();
3228 StringRef FixedName = StringSwitch<StringRef>(Name)
3234 assert(FixedName != "" && "Register name is not one of t4-t7.");
3236 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3237 "Did you mean $" + FixedName + "?", RegRange);
3240 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3241 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3242 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3243 if (8 <= CC && CC <= 11)
3247 CC = StringSwitch<unsigned>(Name)
3259 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3262 CC = StringSwitch<unsigned>(Name)
3263 .Case("hwr_cpunum", 0)
3264 .Case("hwr_synci_step", 1)
3266 .Case("hwr_ccres", 3)
3267 .Case("hwr_ulr", 29)
3273 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3275 if (Name[0] == 'f') {
3276 StringRef NumString = Name.substr(1);
3278 if (NumString.getAsInteger(10, IntVal))
3279 return -1; // This is not an integer.
3280 if (IntVal > 31) // Maximum index for fpu register.
3287 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3289 if (Name.startswith("fcc")) {
3290 StringRef NumString = Name.substr(3);
3292 if (NumString.getAsInteger(10, IntVal))
3293 return -1; // This is not an integer.
3294 if (IntVal > 7) // There are only 8 fcc registers.
3301 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3303 if (Name.startswith("ac")) {
3304 StringRef NumString = Name.substr(2);
3306 if (NumString.getAsInteger(10, IntVal))
3307 return -1; // This is not an integer.
3308 if (IntVal > 3) // There are only 3 acc registers.
3315 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3318 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3327 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3330 CC = StringSwitch<unsigned>(Name)
3333 .Case("msaaccess", 2)
3335 .Case("msamodify", 4)
3336 .Case("msarequest", 5)
3338 .Case("msaunmap", 7)
3344 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3345 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3347 reportParseError(Loc,
3348 "pseudo-instruction requires $at, which is not available");
3351 unsigned AT = getReg(
3352 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3356 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3357 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3360 unsigned MipsAsmParser::getGPR(int RegNo) {
3361 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3365 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3367 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3370 return getReg(RegClass, RegNum);
3373 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3374 MCAsmParser &Parser = getParser();
3375 DEBUG(dbgs() << "parseOperand\n");
3377 // Check if the current operand has a custom associated parser, if so, try to
3378 // custom parse the operand, or fallback to the general approach.
3379 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3380 if (ResTy == MatchOperand_Success)
3382 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3383 // there was a match, but an error occurred, in which case, just return that
3384 // the operand parsing failed.
3385 if (ResTy == MatchOperand_ParseFail)
3388 DEBUG(dbgs() << ".. Generic Parser\n");
3390 switch (getLexer().getKind()) {
3392 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3394 case AsmToken::Dollar: {
3395 // Parse the register.
3396 SMLoc S = Parser.getTok().getLoc();
3398 // Almost all registers have been parsed by custom parsers. There is only
3399 // one exception to this. $zero (and it's alias $0) will reach this point
3400 // for div, divu, and similar instructions because it is not an operand
3401 // to the instruction definition but an explicit register. Special case
3402 // this situation for now.
3403 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3406 // Maybe it is a symbol reference.
3407 StringRef Identifier;
3408 if (Parser.parseIdentifier(Identifier))
3411 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3412 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3413 // Otherwise create a symbol reference.
3415 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3417 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3420 // Else drop to expression parsing.
3421 case AsmToken::LParen:
3422 case AsmToken::Minus:
3423 case AsmToken::Plus:
3424 case AsmToken::Integer:
3425 case AsmToken::Tilde:
3426 case AsmToken::String: {
3427 DEBUG(dbgs() << ".. generic integer\n");
3428 OperandMatchResultTy ResTy = parseImm(Operands);
3429 return ResTy != MatchOperand_Success;
3431 case AsmToken::Percent: {
3432 // It is a symbol reference or constant expression.
3433 const MCExpr *IdVal;
3434 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3435 if (parseRelocOperand(IdVal))
3438 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3440 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3442 } // case AsmToken::Percent
3443 } // switch(getLexer().getKind())
3447 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3448 StringRef RelocStr) {
3450 // Check the type of the expression.
3451 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3452 // It's a constant, evaluate reloc value.
3454 switch (getVariantKind(RelocStr)) {
3455 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3456 // Get the 1st 16-bits.
3457 Val = MCE->getValue() & 0xffff;
3459 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3460 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3461 // 16 bits being negative.
3462 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3464 case MCSymbolRefExpr::VK_Mips_HIGHER:
3465 // Get the 3rd 16-bits.
3466 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3468 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3469 // Get the 4th 16-bits.
3470 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3473 report_fatal_error("unsupported reloc value");
3475 return MCConstantExpr::create(Val, getContext());
3478 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3479 // It's a symbol, create a symbolic expression from the symbol.
3480 const MCSymbol *Symbol = &MSRE->getSymbol();
3481 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3482 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3486 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3487 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3489 // Try to create target expression.
3490 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3491 return MipsMCExpr::create(VK, Expr, getContext());
3493 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3494 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3495 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3499 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3500 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3501 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3504 // Just return the original expression.
3508 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3510 switch (Expr->getKind()) {
3511 case MCExpr::Constant:
3513 case MCExpr::SymbolRef:
3514 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3515 case MCExpr::Binary:
3516 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3517 if (!isEvaluated(BE->getLHS()))
3519 return isEvaluated(BE->getRHS());
3522 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3523 case MCExpr::Target:
3529 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3530 MCAsmParser &Parser = getParser();
3531 Parser.Lex(); // Eat the % token.
3532 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3533 if (Tok.isNot(AsmToken::Identifier))
3536 std::string Str = Tok.getIdentifier();
3538 Parser.Lex(); // Eat the identifier.
3539 // Now make an expression from the rest of the operand.
3540 const MCExpr *IdVal;
3543 if (getLexer().getKind() == AsmToken::LParen) {
3545 Parser.Lex(); // Eat the '(' token.
3546 if (getLexer().getKind() == AsmToken::Percent) {
3547 Parser.Lex(); // Eat the % token.
3548 const AsmToken &nextTok = Parser.getTok();
3549 if (nextTok.isNot(AsmToken::Identifier))
3552 Str += nextTok.getIdentifier();
3553 Parser.Lex(); // Eat the identifier.
3554 if (getLexer().getKind() != AsmToken::LParen)
3559 if (getParser().parseParenExpression(IdVal, EndLoc))
3562 while (getLexer().getKind() == AsmToken::RParen)
3563 Parser.Lex(); // Eat the ')' token.
3566 return true; // Parenthesis must follow the relocation operand.
3568 Res = evaluateRelocExpr(IdVal, Str);
3572 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3574 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3575 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3576 if (ResTy == MatchOperand_Success) {
3577 assert(Operands.size() == 1);
3578 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3579 StartLoc = Operand.getStartLoc();
3580 EndLoc = Operand.getEndLoc();
3582 // AFAIK, we only support numeric registers and named GPR's in CFI
3584 // Don't worry about eating tokens before failing. Using an unrecognised
3585 // register is a parse error.
3586 if (Operand.isGPRAsmReg()) {
3587 // Resolve to GPR32 or GPR64 appropriately.
3588 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3591 return (RegNo == (unsigned)-1);
3594 assert(Operands.size() == 0);
3595 return (RegNo == (unsigned)-1);
3598 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3599 MCAsmParser &Parser = getParser();
3602 unsigned NumOfLParen = 0;
3604 while (getLexer().getKind() == AsmToken::LParen) {
3609 switch (getLexer().getKind()) {
3612 case AsmToken::Identifier:
3613 case AsmToken::LParen:
3614 case AsmToken::Integer:
3615 case AsmToken::Minus:
3616 case AsmToken::Plus:
3618 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3620 Result = (getParser().parseExpression(Res));
3621 while (getLexer().getKind() == AsmToken::RParen)
3624 case AsmToken::Percent:
3625 Result = parseRelocOperand(Res);
3630 MipsAsmParser::OperandMatchResultTy
3631 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3632 MCAsmParser &Parser = getParser();
3633 DEBUG(dbgs() << "parseMemOperand\n");
3634 const MCExpr *IdVal = nullptr;
3636 bool isParenExpr = false;
3637 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3638 // First operand is the offset.
3639 S = Parser.getTok().getLoc();
3641 if (getLexer().getKind() == AsmToken::LParen) {
3646 if (getLexer().getKind() != AsmToken::Dollar) {
3647 if (parseMemOffset(IdVal, isParenExpr))
3648 return MatchOperand_ParseFail;
3650 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3651 if (Tok.isNot(AsmToken::LParen)) {
3652 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3653 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3655 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3656 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3657 return MatchOperand_Success;
3659 if (Tok.is(AsmToken::EndOfStatement)) {
3661 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3663 // Zero register assumed, add a memory operand with ZERO as its base.
3664 // "Base" will be managed by k_Memory.
3665 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3668 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3669 return MatchOperand_Success;
3671 Error(Parser.getTok().getLoc(), "'(' expected");
3672 return MatchOperand_ParseFail;
3675 Parser.Lex(); // Eat the '(' token.
3678 Res = parseAnyRegister(Operands);
3679 if (Res != MatchOperand_Success)
3682 if (Parser.getTok().isNot(AsmToken::RParen)) {
3683 Error(Parser.getTok().getLoc(), "')' expected");
3684 return MatchOperand_ParseFail;
3687 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3689 Parser.Lex(); // Eat the ')' token.
3692 IdVal = MCConstantExpr::create(0, getContext());
3694 // Replace the register operand with the memory operand.
3695 std::unique_ptr<MipsOperand> op(
3696 static_cast<MipsOperand *>(Operands.back().release()));
3697 // Remove the register from the operands.
3698 // "op" will be managed by k_Memory.
3699 Operands.pop_back();
3700 // Add the memory operand.
3701 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3703 if (IdVal->evaluateAsAbsolute(Imm))
3704 IdVal = MCConstantExpr::create(Imm, getContext());
3705 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3706 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3710 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3711 return MatchOperand_Success;
3714 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3715 MCAsmParser &Parser = getParser();
3716 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3718 SMLoc S = Parser.getTok().getLoc();
3720 if (Sym->isVariable())
3721 Expr = Sym->getVariableValue();
3724 if (Expr->getKind() == MCExpr::SymbolRef) {
3725 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3726 StringRef DefSymbol = Ref->getSymbol().getName();
3727 if (DefSymbol.startswith("$")) {
3728 OperandMatchResultTy ResTy =
3729 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3730 if (ResTy == MatchOperand_Success) {
3733 } else if (ResTy == MatchOperand_ParseFail)
3734 llvm_unreachable("Should never ParseFail");
3737 } else if (Expr->getKind() == MCExpr::Constant) {
3739 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3741 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3748 MipsAsmParser::OperandMatchResultTy
3749 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3750 StringRef Identifier,
3752 int Index = matchCPURegisterName(Identifier);
3754 Operands.push_back(MipsOperand::createGPRReg(
3755 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3756 return MatchOperand_Success;
3759 Index = matchHWRegsRegisterName(Identifier);
3761 Operands.push_back(MipsOperand::createHWRegsReg(
3762 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3763 return MatchOperand_Success;
3766 Index = matchFPURegisterName(Identifier);
3768 Operands.push_back(MipsOperand::createFGRReg(
3769 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3770 return MatchOperand_Success;
3773 Index = matchFCCRegisterName(Identifier);
3775 Operands.push_back(MipsOperand::createFCCReg(
3776 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3777 return MatchOperand_Success;
3780 Index = matchACRegisterName(Identifier);
3782 Operands.push_back(MipsOperand::createACCReg(
3783 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3784 return MatchOperand_Success;
3787 Index = matchMSA128RegisterName(Identifier);
3789 Operands.push_back(MipsOperand::createMSA128Reg(
3790 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3791 return MatchOperand_Success;
3794 Index = matchMSA128CtrlRegisterName(Identifier);
3796 Operands.push_back(MipsOperand::createMSACtrlReg(
3797 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3798 return MatchOperand_Success;
3801 return MatchOperand_NoMatch;
3804 MipsAsmParser::OperandMatchResultTy
3805 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3806 MCAsmParser &Parser = getParser();
3807 auto Token = Parser.getLexer().peekTok(false);
3809 if (Token.is(AsmToken::Identifier)) {
3810 DEBUG(dbgs() << ".. identifier\n");
3811 StringRef Identifier = Token.getIdentifier();
3812 OperandMatchResultTy ResTy =
3813 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3815 } else if (Token.is(AsmToken::Integer)) {
3816 DEBUG(dbgs() << ".. integer\n");
3817 Operands.push_back(MipsOperand::createNumericReg(
3818 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3820 return MatchOperand_Success;
3823 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3825 return MatchOperand_NoMatch;
3828 MipsAsmParser::OperandMatchResultTy
3829 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3830 MCAsmParser &Parser = getParser();
3831 DEBUG(dbgs() << "parseAnyRegister\n");
3833 auto Token = Parser.getTok();
3835 SMLoc S = Token.getLoc();
3837 if (Token.isNot(AsmToken::Dollar)) {
3838 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3839 if (Token.is(AsmToken::Identifier)) {
3840 if (searchSymbolAlias(Operands))
3841 return MatchOperand_Success;
3843 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3844 return MatchOperand_NoMatch;
3846 DEBUG(dbgs() << ".. $\n");
3848 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3849 if (ResTy == MatchOperand_Success) {
3851 Parser.Lex(); // identifier
3856 MipsAsmParser::OperandMatchResultTy
3857 MipsAsmParser::parseImm(OperandVector &Operands) {
3858 MCAsmParser &Parser = getParser();
3859 switch (getLexer().getKind()) {
3861 return MatchOperand_NoMatch;
3862 case AsmToken::LParen:
3863 case AsmToken::Minus:
3864 case AsmToken::Plus:
3865 case AsmToken::Integer:
3866 case AsmToken::Tilde:
3867 case AsmToken::String:
3871 const MCExpr *IdVal;
3872 SMLoc S = Parser.getTok().getLoc();
3873 if (getParser().parseExpression(IdVal))
3874 return MatchOperand_ParseFail;
3876 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3877 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3878 return MatchOperand_Success;
3881 MipsAsmParser::OperandMatchResultTy
3882 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3883 MCAsmParser &Parser = getParser();
3884 DEBUG(dbgs() << "parseJumpTarget\n");
3886 SMLoc S = getLexer().getLoc();
3888 // Integers and expressions are acceptable
3889 OperandMatchResultTy ResTy = parseImm(Operands);
3890 if (ResTy != MatchOperand_NoMatch)
3893 // Registers are a valid target and have priority over symbols.
3894 ResTy = parseAnyRegister(Operands);
3895 if (ResTy != MatchOperand_NoMatch)
3898 const MCExpr *Expr = nullptr;
3899 if (Parser.parseExpression(Expr)) {
3900 // We have no way of knowing if a symbol was consumed so we must ParseFail
3901 return MatchOperand_ParseFail;
3904 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3905 return MatchOperand_Success;
3908 MipsAsmParser::OperandMatchResultTy
3909 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3910 MCAsmParser &Parser = getParser();
3911 const MCExpr *IdVal;
3912 // If the first token is '$' we may have register operand.
3913 if (Parser.getTok().is(AsmToken::Dollar))
3914 return MatchOperand_NoMatch;
3915 SMLoc S = Parser.getTok().getLoc();
3916 if (getParser().parseExpression(IdVal))
3917 return MatchOperand_ParseFail;
3918 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3919 assert(MCE && "Unexpected MCExpr type.");
3920 int64_t Val = MCE->getValue();
3921 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3922 Operands.push_back(MipsOperand::CreateImm(
3923 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3924 return MatchOperand_Success;
3927 MipsAsmParser::OperandMatchResultTy
3928 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3929 MCAsmParser &Parser = getParser();
3930 switch (getLexer().getKind()) {
3932 return MatchOperand_NoMatch;
3933 case AsmToken::LParen:
3934 case AsmToken::Plus:
3935 case AsmToken::Minus:
3936 case AsmToken::Integer:
3941 SMLoc S = Parser.getTok().getLoc();
3943 if (getParser().parseExpression(Expr))
3944 return MatchOperand_ParseFail;
3947 if (!Expr->evaluateAsAbsolute(Val)) {
3948 Error(S, "expected immediate value");
3949 return MatchOperand_ParseFail;
3952 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3953 // and because the CPU always adds one to the immediate field, the allowed
3954 // range becomes 1..4. We'll only check the range here and will deal
3955 // with the addition/subtraction when actually decoding/encoding
3957 if (Val < 1 || Val > 4) {
3958 Error(S, "immediate not in range (1..4)");
3959 return MatchOperand_ParseFail;
3963 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3964 return MatchOperand_Success;
3967 MipsAsmParser::OperandMatchResultTy
3968 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3969 MCAsmParser &Parser = getParser();
3970 SmallVector<unsigned, 10> Regs;
3972 unsigned PrevReg = Mips::NoRegister;
3973 bool RegRange = false;
3974 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3976 if (Parser.getTok().isNot(AsmToken::Dollar))
3977 return MatchOperand_ParseFail;
3979 SMLoc S = Parser.getTok().getLoc();
3980 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3981 SMLoc E = getLexer().getLoc();
3982 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3983 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3985 // Remove last register operand because registers from register range
3986 // should be inserted first.
3987 if (RegNo == Mips::RA) {
3988 Regs.push_back(RegNo);
3990 unsigned TmpReg = PrevReg + 1;
3991 while (TmpReg <= RegNo) {
3992 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3993 Error(E, "invalid register operand");
3994 return MatchOperand_ParseFail;
3998 Regs.push_back(TmpReg++);
4004 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4005 (RegNo != Mips::RA)) {
4006 Error(E, "$16 or $31 expected");
4007 return MatchOperand_ParseFail;
4008 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4009 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4010 Error(E, "invalid register operand");
4011 return MatchOperand_ParseFail;
4012 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4013 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4014 Error(E, "consecutive register numbers expected");
4015 return MatchOperand_ParseFail;
4018 Regs.push_back(RegNo);
4021 if (Parser.getTok().is(AsmToken::Minus))
4024 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4025 !Parser.getTok().isNot(AsmToken::Comma)) {
4026 Error(E, "',' or '-' expected");
4027 return MatchOperand_ParseFail;
4030 Lex(); // Consume comma or minus
4031 if (Parser.getTok().isNot(AsmToken::Dollar))
4037 SMLoc E = Parser.getTok().getLoc();
4038 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4039 parseMemOperand(Operands);
4040 return MatchOperand_Success;
4043 MipsAsmParser::OperandMatchResultTy
4044 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4045 MCAsmParser &Parser = getParser();
4047 SMLoc S = Parser.getTok().getLoc();
4048 if (parseAnyRegister(Operands) != MatchOperand_Success)
4049 return MatchOperand_ParseFail;
4051 SMLoc E = Parser.getTok().getLoc();
4052 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4053 unsigned Reg = Op.getGPR32Reg();
4054 Operands.pop_back();
4055 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4056 return MatchOperand_Success;
4059 MipsAsmParser::OperandMatchResultTy
4060 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4061 MCAsmParser &Parser = getParser();
4062 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4063 SmallVector<unsigned, 10> Regs;
4065 if (Parser.getTok().isNot(AsmToken::Dollar))
4066 return MatchOperand_ParseFail;
4068 SMLoc S = Parser.getTok().getLoc();
4070 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4071 return MatchOperand_ParseFail;
4073 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4074 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4075 Regs.push_back(RegNo);
4077 SMLoc E = Parser.getTok().getLoc();
4078 if (Parser.getTok().isNot(AsmToken::Comma)) {
4079 Error(E, "',' expected");
4080 return MatchOperand_ParseFail;
4086 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4087 return MatchOperand_ParseFail;
4089 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4090 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4091 Regs.push_back(RegNo);
4093 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4095 return MatchOperand_Success;
4098 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4100 MCSymbolRefExpr::VariantKind VK =
4101 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4102 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4103 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4104 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4105 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4106 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4107 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4108 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4109 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4110 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4111 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4112 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4113 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4114 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4115 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4116 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4117 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4118 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4119 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4120 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4121 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4122 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4123 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4124 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4125 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4126 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4127 .Default(MCSymbolRefExpr::VK_None);
4129 assert(VK != MCSymbolRefExpr::VK_None);
4134 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4136 /// ::= '(', register, ')'
4137 /// handle it before we iterate so we don't get tripped up by the lack of
4139 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4140 MCAsmParser &Parser = getParser();
4141 if (getLexer().is(AsmToken::LParen)) {
4143 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4145 if (parseOperand(Operands, Name)) {
4146 SMLoc Loc = getLexer().getLoc();
4147 Parser.eatToEndOfStatement();
4148 return Error(Loc, "unexpected token in argument list");
4150 if (Parser.getTok().isNot(AsmToken::RParen)) {
4151 SMLoc Loc = getLexer().getLoc();
4152 Parser.eatToEndOfStatement();
4153 return Error(Loc, "unexpected token, expected ')'");
4156 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4162 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4163 /// either one of these.
4164 /// ::= '[', register, ']'
4165 /// ::= '[', integer, ']'
4166 /// handle it before we iterate so we don't get tripped up by the lack of
4168 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4169 OperandVector &Operands) {
4170 MCAsmParser &Parser = getParser();
4171 if (getLexer().is(AsmToken::LBrac)) {
4173 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4175 if (parseOperand(Operands, Name)) {
4176 SMLoc Loc = getLexer().getLoc();
4177 Parser.eatToEndOfStatement();
4178 return Error(Loc, "unexpected token in argument list");
4180 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4181 SMLoc Loc = getLexer().getLoc();
4182 Parser.eatToEndOfStatement();
4183 return Error(Loc, "unexpected token, expected ']'");
4186 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4192 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4193 SMLoc NameLoc, OperandVector &Operands) {
4194 MCAsmParser &Parser = getParser();
4195 DEBUG(dbgs() << "ParseInstruction\n");
4197 // We have reached first instruction, module directive are now forbidden.
4198 getTargetStreamer().forbidModuleDirective();
4200 // Check if we have valid mnemonic
4201 if (!mnemonicIsValid(Name, 0)) {
4202 Parser.eatToEndOfStatement();
4203 return Error(NameLoc, "unknown instruction");
4205 // First operand in MCInst is instruction mnemonic.
4206 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4208 // Read the remaining operands.
4209 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4210 // Read the first operand.
4211 if (parseOperand(Operands, Name)) {
4212 SMLoc Loc = getLexer().getLoc();
4213 Parser.eatToEndOfStatement();
4214 return Error(Loc, "unexpected token in argument list");
4216 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4218 // AFAIK, parenthesis suffixes are never on the first operand
4220 while (getLexer().is(AsmToken::Comma)) {
4221 Parser.Lex(); // Eat the comma.
4222 // Parse and remember the operand.
4223 if (parseOperand(Operands, Name)) {
4224 SMLoc Loc = getLexer().getLoc();
4225 Parser.eatToEndOfStatement();
4226 return Error(Loc, "unexpected token in argument list");
4228 // Parse bracket and parenthesis suffixes before we iterate
4229 if (getLexer().is(AsmToken::LBrac)) {
4230 if (parseBracketSuffix(Name, Operands))
4232 } else if (getLexer().is(AsmToken::LParen) &&
4233 parseParenSuffix(Name, Operands))
4237 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4238 SMLoc Loc = getLexer().getLoc();
4239 Parser.eatToEndOfStatement();
4240 return Error(Loc, "unexpected token in argument list");
4242 Parser.Lex(); // Consume the EndOfStatement.
4246 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4247 MCAsmParser &Parser = getParser();
4248 SMLoc Loc = getLexer().getLoc();
4249 Parser.eatToEndOfStatement();
4250 return Error(Loc, ErrorMsg);
4253 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4254 return Error(Loc, ErrorMsg);
4257 bool MipsAsmParser::parseSetNoAtDirective() {
4258 MCAsmParser &Parser = getParser();
4259 // Line should look like: ".set noat".
4261 // Set the $at register to $0.
4262 AssemblerOptions.back()->setATRegIndex(0);
4264 Parser.Lex(); // Eat "noat".
4266 // If this is not the end of the statement, report an error.
4267 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4268 reportParseError("unexpected token, expected end of statement");
4272 getTargetStreamer().emitDirectiveSetNoAt();
4273 Parser.Lex(); // Consume the EndOfStatement.
4277 bool MipsAsmParser::parseSetAtDirective() {
4278 // Line can be: ".set at", which sets $at to $1
4279 // or ".set at=$reg", which sets $at to $reg.
4280 MCAsmParser &Parser = getParser();
4281 Parser.Lex(); // Eat "at".
4283 if (getLexer().is(AsmToken::EndOfStatement)) {
4284 // No register was specified, so we set $at to $1.
4285 AssemblerOptions.back()->setATRegIndex(1);
4287 getTargetStreamer().emitDirectiveSetAt();
4288 Parser.Lex(); // Consume the EndOfStatement.
4292 if (getLexer().isNot(AsmToken::Equal)) {
4293 reportParseError("unexpected token, expected equals sign");
4296 Parser.Lex(); // Eat "=".
4298 if (getLexer().isNot(AsmToken::Dollar)) {
4299 if (getLexer().is(AsmToken::EndOfStatement)) {
4300 reportParseError("no register specified");
4303 reportParseError("unexpected token, expected dollar sign '$'");
4307 Parser.Lex(); // Eat "$".
4309 // Find out what "reg" is.
4311 const AsmToken &Reg = Parser.getTok();
4312 if (Reg.is(AsmToken::Identifier)) {
4313 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4314 } else if (Reg.is(AsmToken::Integer)) {
4315 AtRegNo = Reg.getIntVal();
4317 reportParseError("unexpected token, expected identifier or integer");
4321 // Check if $reg is a valid register. If it is, set $at to $reg.
4322 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4323 reportParseError("invalid register");
4326 Parser.Lex(); // Eat "reg".
4328 // If this is not the end of the statement, report an error.
4329 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4330 reportParseError("unexpected token, expected end of statement");
4334 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4336 Parser.Lex(); // Consume the EndOfStatement.
4340 bool MipsAsmParser::parseSetReorderDirective() {
4341 MCAsmParser &Parser = getParser();
4343 // If this is not the end of the statement, report an error.
4344 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4345 reportParseError("unexpected token, expected end of statement");
4348 AssemblerOptions.back()->setReorder();
4349 getTargetStreamer().emitDirectiveSetReorder();
4350 Parser.Lex(); // Consume the EndOfStatement.
4354 bool MipsAsmParser::parseSetNoReorderDirective() {
4355 MCAsmParser &Parser = getParser();
4357 // If this is not the end of the statement, report an error.
4358 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4359 reportParseError("unexpected token, expected end of statement");
4362 AssemblerOptions.back()->setNoReorder();
4363 getTargetStreamer().emitDirectiveSetNoReorder();
4364 Parser.Lex(); // Consume the EndOfStatement.
4368 bool MipsAsmParser::parseSetMacroDirective() {
4369 MCAsmParser &Parser = getParser();
4371 // If this is not the end of the statement, report an error.
4372 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4373 reportParseError("unexpected token, expected end of statement");
4376 AssemblerOptions.back()->setMacro();
4377 getTargetStreamer().emitDirectiveSetMacro();
4378 Parser.Lex(); // Consume the EndOfStatement.
4382 bool MipsAsmParser::parseSetNoMacroDirective() {
4383 MCAsmParser &Parser = getParser();
4385 // If this is not the end of the statement, report an error.
4386 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4387 reportParseError("unexpected token, expected end of statement");
4390 if (AssemblerOptions.back()->isReorder()) {
4391 reportParseError("`noreorder' must be set before `nomacro'");
4394 AssemblerOptions.back()->setNoMacro();
4395 getTargetStreamer().emitDirectiveSetNoMacro();
4396 Parser.Lex(); // Consume the EndOfStatement.
4400 bool MipsAsmParser::parseSetMsaDirective() {
4401 MCAsmParser &Parser = getParser();
4404 // If this is not the end of the statement, report an error.
4405 if (getLexer().isNot(AsmToken::EndOfStatement))
4406 return reportParseError("unexpected token, expected end of statement");
4408 setFeatureBits(Mips::FeatureMSA, "msa");
4409 getTargetStreamer().emitDirectiveSetMsa();
4413 bool MipsAsmParser::parseSetNoMsaDirective() {
4414 MCAsmParser &Parser = getParser();
4417 // If this is not the end of the statement, report an error.
4418 if (getLexer().isNot(AsmToken::EndOfStatement))
4419 return reportParseError("unexpected token, expected end of statement");
4421 clearFeatureBits(Mips::FeatureMSA, "msa");
4422 getTargetStreamer().emitDirectiveSetNoMsa();
4426 bool MipsAsmParser::parseSetNoDspDirective() {
4427 MCAsmParser &Parser = getParser();
4428 Parser.Lex(); // Eat "nodsp".
4430 // If this is not the end of the statement, report an error.
4431 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4432 reportParseError("unexpected token, expected end of statement");
4436 clearFeatureBits(Mips::FeatureDSP, "dsp");
4437 getTargetStreamer().emitDirectiveSetNoDsp();
4441 bool MipsAsmParser::parseSetMips16Directive() {
4442 MCAsmParser &Parser = getParser();
4443 Parser.Lex(); // Eat "mips16".
4445 // If this is not the end of the statement, report an error.
4446 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4447 reportParseError("unexpected token, expected end of statement");
4451 setFeatureBits(Mips::FeatureMips16, "mips16");
4452 getTargetStreamer().emitDirectiveSetMips16();
4453 Parser.Lex(); // Consume the EndOfStatement.
4457 bool MipsAsmParser::parseSetNoMips16Directive() {
4458 MCAsmParser &Parser = getParser();
4459 Parser.Lex(); // Eat "nomips16".
4461 // If this is not the end of the statement, report an error.
4462 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4463 reportParseError("unexpected token, expected end of statement");
4467 clearFeatureBits(Mips::FeatureMips16, "mips16");
4468 getTargetStreamer().emitDirectiveSetNoMips16();
4469 Parser.Lex(); // Consume the EndOfStatement.
4473 bool MipsAsmParser::parseSetFpDirective() {
4474 MCAsmParser &Parser = getParser();
4475 MipsABIFlagsSection::FpABIKind FpAbiVal;
4476 // Line can be: .set fp=32
4479 Parser.Lex(); // Eat fp token
4480 AsmToken Tok = Parser.getTok();
4481 if (Tok.isNot(AsmToken::Equal)) {
4482 reportParseError("unexpected token, expected equals sign '='");
4485 Parser.Lex(); // Eat '=' token.
4486 Tok = Parser.getTok();
4488 if (!parseFpABIValue(FpAbiVal, ".set"))
4491 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4492 reportParseError("unexpected token, expected end of statement");
4495 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4496 Parser.Lex(); // Consume the EndOfStatement.
4500 bool MipsAsmParser::parseSetOddSPRegDirective() {
4501 MCAsmParser &Parser = getParser();
4503 Parser.Lex(); // Eat "oddspreg".
4504 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4505 reportParseError("unexpected token, expected end of statement");
4509 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4510 getTargetStreamer().emitDirectiveSetOddSPReg();
4514 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4515 MCAsmParser &Parser = getParser();
4517 Parser.Lex(); // Eat "nooddspreg".
4518 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4519 reportParseError("unexpected token, expected end of statement");
4523 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4524 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4528 bool MipsAsmParser::parseSetPopDirective() {
4529 MCAsmParser &Parser = getParser();
4530 SMLoc Loc = getLexer().getLoc();
4533 if (getLexer().isNot(AsmToken::EndOfStatement))
4534 return reportParseError("unexpected token, expected end of statement");
4536 // Always keep an element on the options "stack" to prevent the user
4537 // from changing the initial options. This is how we remember them.
4538 if (AssemblerOptions.size() == 2)
4539 return reportParseError(Loc, ".set pop with no .set push");
4541 AssemblerOptions.pop_back();
4542 setAvailableFeatures(
4543 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4544 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4546 getTargetStreamer().emitDirectiveSetPop();
4550 bool MipsAsmParser::parseSetPushDirective() {
4551 MCAsmParser &Parser = getParser();
4553 if (getLexer().isNot(AsmToken::EndOfStatement))
4554 return reportParseError("unexpected token, expected end of statement");
4556 // Create a copy of the current assembler options environment and push it.
4557 AssemblerOptions.push_back(
4558 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4560 getTargetStreamer().emitDirectiveSetPush();
4564 bool MipsAsmParser::parseSetSoftFloatDirective() {
4565 MCAsmParser &Parser = getParser();
4567 if (getLexer().isNot(AsmToken::EndOfStatement))
4568 return reportParseError("unexpected token, expected end of statement");
4570 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4571 getTargetStreamer().emitDirectiveSetSoftFloat();
4575 bool MipsAsmParser::parseSetHardFloatDirective() {
4576 MCAsmParser &Parser = getParser();
4578 if (getLexer().isNot(AsmToken::EndOfStatement))
4579 return reportParseError("unexpected token, expected end of statement");
4581 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4582 getTargetStreamer().emitDirectiveSetHardFloat();
4586 bool MipsAsmParser::parseSetAssignment() {
4588 const MCExpr *Value;
4589 MCAsmParser &Parser = getParser();
4591 if (Parser.parseIdentifier(Name))
4592 reportParseError("expected identifier after .set");
4594 if (getLexer().isNot(AsmToken::Comma))
4595 return reportParseError("unexpected token, expected comma");
4598 if (Parser.parseExpression(Value))
4599 return reportParseError("expected valid expression after comma");
4601 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4602 Sym->setVariableValue(Value);
4607 bool MipsAsmParser::parseSetMips0Directive() {
4608 MCAsmParser &Parser = getParser();
4610 if (getLexer().isNot(AsmToken::EndOfStatement))
4611 return reportParseError("unexpected token, expected end of statement");
4613 // Reset assembler options to their initial values.
4614 setAvailableFeatures(
4615 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4616 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4617 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4619 getTargetStreamer().emitDirectiveSetMips0();
4623 bool MipsAsmParser::parseSetArchDirective() {
4624 MCAsmParser &Parser = getParser();
4626 if (getLexer().isNot(AsmToken::Equal))
4627 return reportParseError("unexpected token, expected equals sign");
4631 if (Parser.parseIdentifier(Arch))
4632 return reportParseError("expected arch identifier");
4634 StringRef ArchFeatureName =
4635 StringSwitch<StringRef>(Arch)
4636 .Case("mips1", "mips1")
4637 .Case("mips2", "mips2")
4638 .Case("mips3", "mips3")
4639 .Case("mips4", "mips4")
4640 .Case("mips5", "mips5")
4641 .Case("mips32", "mips32")
4642 .Case("mips32r2", "mips32r2")
4643 .Case("mips32r3", "mips32r3")
4644 .Case("mips32r5", "mips32r5")
4645 .Case("mips32r6", "mips32r6")
4646 .Case("mips64", "mips64")
4647 .Case("mips64r2", "mips64r2")
4648 .Case("mips64r3", "mips64r3")
4649 .Case("mips64r5", "mips64r5")
4650 .Case("mips64r6", "mips64r6")
4651 .Case("cnmips", "cnmips")
4652 .Case("r4000", "mips3") // This is an implementation of Mips3.
4655 if (ArchFeatureName.empty())
4656 return reportParseError("unsupported architecture");
4658 selectArch(ArchFeatureName);
4659 getTargetStreamer().emitDirectiveSetArch(Arch);
4663 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4664 MCAsmParser &Parser = getParser();
4666 if (getLexer().isNot(AsmToken::EndOfStatement))
4667 return reportParseError("unexpected token, expected end of statement");
4671 llvm_unreachable("Unimplemented feature");
4672 case Mips::FeatureDSP:
4673 setFeatureBits(Mips::FeatureDSP, "dsp");
4674 getTargetStreamer().emitDirectiveSetDsp();
4676 case Mips::FeatureMicroMips:
4677 getTargetStreamer().emitDirectiveSetMicroMips();
4679 case Mips::FeatureMips1:
4680 selectArch("mips1");
4681 getTargetStreamer().emitDirectiveSetMips1();
4683 case Mips::FeatureMips2:
4684 selectArch("mips2");
4685 getTargetStreamer().emitDirectiveSetMips2();
4687 case Mips::FeatureMips3:
4688 selectArch("mips3");
4689 getTargetStreamer().emitDirectiveSetMips3();
4691 case Mips::FeatureMips4:
4692 selectArch("mips4");
4693 getTargetStreamer().emitDirectiveSetMips4();
4695 case Mips::FeatureMips5:
4696 selectArch("mips5");
4697 getTargetStreamer().emitDirectiveSetMips5();
4699 case Mips::FeatureMips32:
4700 selectArch("mips32");
4701 getTargetStreamer().emitDirectiveSetMips32();
4703 case Mips::FeatureMips32r2:
4704 selectArch("mips32r2");
4705 getTargetStreamer().emitDirectiveSetMips32R2();
4707 case Mips::FeatureMips32r3:
4708 selectArch("mips32r3");
4709 getTargetStreamer().emitDirectiveSetMips32R3();
4711 case Mips::FeatureMips32r5:
4712 selectArch("mips32r5");
4713 getTargetStreamer().emitDirectiveSetMips32R5();
4715 case Mips::FeatureMips32r6:
4716 selectArch("mips32r6");
4717 getTargetStreamer().emitDirectiveSetMips32R6();
4719 case Mips::FeatureMips64:
4720 selectArch("mips64");
4721 getTargetStreamer().emitDirectiveSetMips64();
4723 case Mips::FeatureMips64r2:
4724 selectArch("mips64r2");
4725 getTargetStreamer().emitDirectiveSetMips64R2();
4727 case Mips::FeatureMips64r3:
4728 selectArch("mips64r3");
4729 getTargetStreamer().emitDirectiveSetMips64R3();
4731 case Mips::FeatureMips64r5:
4732 selectArch("mips64r5");
4733 getTargetStreamer().emitDirectiveSetMips64R5();
4735 case Mips::FeatureMips64r6:
4736 selectArch("mips64r6");
4737 getTargetStreamer().emitDirectiveSetMips64R6();
4743 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4744 MCAsmParser &Parser = getParser();
4745 if (getLexer().isNot(AsmToken::Comma)) {
4746 SMLoc Loc = getLexer().getLoc();
4747 Parser.eatToEndOfStatement();
4748 return Error(Loc, ErrorStr);
4751 Parser.Lex(); // Eat the comma.
4755 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4756 if (AssemblerOptions.back()->isReorder())
4757 Warning(Loc, ".cpload should be inside a noreorder section");
4759 if (inMips16Mode()) {
4760 reportParseError(".cpload is not supported in Mips16 mode");
4764 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4765 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4766 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4767 reportParseError("expected register containing function address");
4771 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4772 if (!RegOpnd.isGPRAsmReg()) {
4773 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4777 // If this is not the end of the statement, report an error.
4778 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4779 reportParseError("unexpected token, expected end of statement");
4783 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4787 bool MipsAsmParser::parseDirectiveCPSetup() {
4788 MCAsmParser &Parser = getParser();
4791 bool SaveIsReg = true;
4793 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4794 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4795 if (ResTy == MatchOperand_NoMatch) {
4796 reportParseError("expected register containing function address");
4797 Parser.eatToEndOfStatement();
4801 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4802 if (!FuncRegOpnd.isGPRAsmReg()) {
4803 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4804 Parser.eatToEndOfStatement();
4808 FuncReg = FuncRegOpnd.getGPR32Reg();
4811 if (!eatComma("unexpected token, expected comma"))
4814 ResTy = parseAnyRegister(TmpReg);
4815 if (ResTy == MatchOperand_NoMatch) {
4816 const AsmToken &Tok = Parser.getTok();
4817 if (Tok.is(AsmToken::Integer)) {
4818 Save = Tok.getIntVal();
4822 reportParseError("expected save register or stack offset");
4823 Parser.eatToEndOfStatement();
4827 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4828 if (!SaveOpnd.isGPRAsmReg()) {
4829 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4830 Parser.eatToEndOfStatement();
4833 Save = SaveOpnd.getGPR32Reg();
4836 if (!eatComma("unexpected token, expected comma"))
4840 if (Parser.parseExpression(Expr)) {
4841 reportParseError("expected expression");
4845 if (Expr->getKind() != MCExpr::SymbolRef) {
4846 reportParseError("expected symbol");
4849 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4851 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4856 bool MipsAsmParser::parseDirectiveNaN() {
4857 MCAsmParser &Parser = getParser();
4858 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4859 const AsmToken &Tok = Parser.getTok();
4861 if (Tok.getString() == "2008") {
4863 getTargetStreamer().emitDirectiveNaN2008();
4865 } else if (Tok.getString() == "legacy") {
4867 getTargetStreamer().emitDirectiveNaNLegacy();
4871 // If we don't recognize the option passed to the .nan
4872 // directive (e.g. no option or unknown option), emit an error.
4873 reportParseError("invalid option in .nan directive");
4877 bool MipsAsmParser::parseDirectiveSet() {
4878 MCAsmParser &Parser = getParser();
4879 // Get the next token.
4880 const AsmToken &Tok = Parser.getTok();
4882 if (Tok.getString() == "noat") {
4883 return parseSetNoAtDirective();
4884 } else if (Tok.getString() == "at") {
4885 return parseSetAtDirective();
4886 } else if (Tok.getString() == "arch") {
4887 return parseSetArchDirective();
4888 } else if (Tok.getString() == "fp") {
4889 return parseSetFpDirective();
4890 } else if (Tok.getString() == "oddspreg") {
4891 return parseSetOddSPRegDirective();
4892 } else if (Tok.getString() == "nooddspreg") {
4893 return parseSetNoOddSPRegDirective();
4894 } else if (Tok.getString() == "pop") {
4895 return parseSetPopDirective();
4896 } else if (Tok.getString() == "push") {
4897 return parseSetPushDirective();
4898 } else if (Tok.getString() == "reorder") {
4899 return parseSetReorderDirective();
4900 } else if (Tok.getString() == "noreorder") {
4901 return parseSetNoReorderDirective();
4902 } else if (Tok.getString() == "macro") {
4903 return parseSetMacroDirective();
4904 } else if (Tok.getString() == "nomacro") {
4905 return parseSetNoMacroDirective();
4906 } else if (Tok.getString() == "mips16") {
4907 return parseSetMips16Directive();
4908 } else if (Tok.getString() == "nomips16") {
4909 return parseSetNoMips16Directive();
4910 } else if (Tok.getString() == "nomicromips") {
4911 getTargetStreamer().emitDirectiveSetNoMicroMips();
4912 Parser.eatToEndOfStatement();
4914 } else if (Tok.getString() == "micromips") {
4915 return parseSetFeature(Mips::FeatureMicroMips);
4916 } else if (Tok.getString() == "mips0") {
4917 return parseSetMips0Directive();
4918 } else if (Tok.getString() == "mips1") {
4919 return parseSetFeature(Mips::FeatureMips1);
4920 } else if (Tok.getString() == "mips2") {
4921 return parseSetFeature(Mips::FeatureMips2);
4922 } else if (Tok.getString() == "mips3") {
4923 return parseSetFeature(Mips::FeatureMips3);
4924 } else if (Tok.getString() == "mips4") {
4925 return parseSetFeature(Mips::FeatureMips4);
4926 } else if (Tok.getString() == "mips5") {
4927 return parseSetFeature(Mips::FeatureMips5);
4928 } else if (Tok.getString() == "mips32") {
4929 return parseSetFeature(Mips::FeatureMips32);
4930 } else if (Tok.getString() == "mips32r2") {
4931 return parseSetFeature(Mips::FeatureMips32r2);
4932 } else if (Tok.getString() == "mips32r3") {
4933 return parseSetFeature(Mips::FeatureMips32r3);
4934 } else if (Tok.getString() == "mips32r5") {
4935 return parseSetFeature(Mips::FeatureMips32r5);
4936 } else if (Tok.getString() == "mips32r6") {
4937 return parseSetFeature(Mips::FeatureMips32r6);
4938 } else if (Tok.getString() == "mips64") {
4939 return parseSetFeature(Mips::FeatureMips64);
4940 } else if (Tok.getString() == "mips64r2") {
4941 return parseSetFeature(Mips::FeatureMips64r2);
4942 } else if (Tok.getString() == "mips64r3") {
4943 return parseSetFeature(Mips::FeatureMips64r3);
4944 } else if (Tok.getString() == "mips64r5") {
4945 return parseSetFeature(Mips::FeatureMips64r5);
4946 } else if (Tok.getString() == "mips64r6") {
4947 return parseSetFeature(Mips::FeatureMips64r6);
4948 } else if (Tok.getString() == "dsp") {
4949 return parseSetFeature(Mips::FeatureDSP);
4950 } else if (Tok.getString() == "nodsp") {
4951 return parseSetNoDspDirective();
4952 } else if (Tok.getString() == "msa") {
4953 return parseSetMsaDirective();
4954 } else if (Tok.getString() == "nomsa") {
4955 return parseSetNoMsaDirective();
4956 } else if (Tok.getString() == "softfloat") {
4957 return parseSetSoftFloatDirective();
4958 } else if (Tok.getString() == "hardfloat") {
4959 return parseSetHardFloatDirective();
4961 // It is just an identifier, look for an assignment.
4962 parseSetAssignment();
4969 /// parseDataDirective
4970 /// ::= .word [ expression (, expression)* ]
4971 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4972 MCAsmParser &Parser = getParser();
4973 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4975 const MCExpr *Value;
4976 if (getParser().parseExpression(Value))
4979 getParser().getStreamer().EmitValue(Value, Size);
4981 if (getLexer().is(AsmToken::EndOfStatement))
4984 if (getLexer().isNot(AsmToken::Comma))
4985 return Error(L, "unexpected token, expected comma");
4994 /// parseDirectiveGpWord
4995 /// ::= .gpword local_sym
4996 bool MipsAsmParser::parseDirectiveGpWord() {
4997 MCAsmParser &Parser = getParser();
4998 const MCExpr *Value;
4999 // EmitGPRel32Value requires an expression, so we are using base class
5000 // method to evaluate the expression.
5001 if (getParser().parseExpression(Value))
5003 getParser().getStreamer().EmitGPRel32Value(Value);
5005 if (getLexer().isNot(AsmToken::EndOfStatement))
5006 return Error(getLexer().getLoc(),
5007 "unexpected token, expected end of statement");
5008 Parser.Lex(); // Eat EndOfStatement token.
5012 /// parseDirectiveGpDWord
5013 /// ::= .gpdword local_sym
5014 bool MipsAsmParser::parseDirectiveGpDWord() {
5015 MCAsmParser &Parser = getParser();
5016 const MCExpr *Value;
5017 // EmitGPRel64Value requires an expression, so we are using base class
5018 // method to evaluate the expression.
5019 if (getParser().parseExpression(Value))
5021 getParser().getStreamer().EmitGPRel64Value(Value);
5023 if (getLexer().isNot(AsmToken::EndOfStatement))
5024 return Error(getLexer().getLoc(),
5025 "unexpected token, expected end of statement");
5026 Parser.Lex(); // Eat EndOfStatement token.
5030 bool MipsAsmParser::parseDirectiveOption() {
5031 MCAsmParser &Parser = getParser();
5032 // Get the option token.
5033 AsmToken Tok = Parser.getTok();
5034 // At the moment only identifiers are supported.
5035 if (Tok.isNot(AsmToken::Identifier)) {
5036 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5037 Parser.eatToEndOfStatement();
5041 StringRef Option = Tok.getIdentifier();
5043 if (Option == "pic0") {
5044 // MipsAsmParser needs to know if the current PIC mode changes.
5045 IsPicEnabled = false;
5047 getTargetStreamer().emitDirectiveOptionPic0();
5049 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5050 Error(Parser.getTok().getLoc(),
5051 "unexpected token, expected end of statement");
5052 Parser.eatToEndOfStatement();
5057 if (Option == "pic2") {
5058 // MipsAsmParser needs to know if the current PIC mode changes.
5059 IsPicEnabled = true;
5061 getTargetStreamer().emitDirectiveOptionPic2();
5063 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5064 Error(Parser.getTok().getLoc(),
5065 "unexpected token, expected end of statement");
5066 Parser.eatToEndOfStatement();
5072 Warning(Parser.getTok().getLoc(),
5073 "unknown option, expected 'pic0' or 'pic2'");
5074 Parser.eatToEndOfStatement();
5078 /// parseInsnDirective
5080 bool MipsAsmParser::parseInsnDirective() {
5081 // If this is not the end of the statement, report an error.
5082 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5083 reportParseError("unexpected token, expected end of statement");
5087 // The actual label marking happens in
5088 // MipsELFStreamer::createPendingLabelRelocs().
5089 getTargetStreamer().emitDirectiveInsn();
5091 getParser().Lex(); // Eat EndOfStatement token.
5095 /// parseDirectiveModule
5096 /// ::= .module oddspreg
5097 /// ::= .module nooddspreg
5098 /// ::= .module fp=value
5099 /// ::= .module softfloat
5100 /// ::= .module hardfloat
5101 bool MipsAsmParser::parseDirectiveModule() {
5102 MCAsmParser &Parser = getParser();
5103 MCAsmLexer &Lexer = getLexer();
5104 SMLoc L = Lexer.getLoc();
5106 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5107 // TODO : get a better message.
5108 reportParseError(".module directive must appear before any code");
5113 if (Parser.parseIdentifier(Option)) {
5114 reportParseError("expected .module option identifier");
5118 if (Option == "oddspreg") {
5119 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5121 // Synchronize the abiflags information with the FeatureBits information we
5123 getTargetStreamer().updateABIInfo(*this);
5125 // If printing assembly, use the recently updated abiflags information.
5126 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5127 // emitted at the end).
5128 getTargetStreamer().emitDirectiveModuleOddSPReg();
5130 // If this is not the end of the statement, report an error.
5131 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5132 reportParseError("unexpected token, expected end of statement");
5136 return false; // parseDirectiveModule has finished successfully.
5137 } else if (Option == "nooddspreg") {
5139 Error(L, "'.module nooddspreg' requires the O32 ABI");
5143 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5145 // Synchronize the abiflags information with the FeatureBits information we
5147 getTargetStreamer().updateABIInfo(*this);
5149 // If printing assembly, use the recently updated abiflags information.
5150 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5151 // emitted at the end).
5152 getTargetStreamer().emitDirectiveModuleOddSPReg();
5154 // If this is not the end of the statement, report an error.
5155 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5156 reportParseError("unexpected token, expected end of statement");
5160 return false; // parseDirectiveModule has finished successfully.
5161 } else if (Option == "fp") {
5162 return parseDirectiveModuleFP();
5163 } else if (Option == "softfloat") {
5164 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5166 // Synchronize the ABI Flags information with the FeatureBits information we
5168 getTargetStreamer().updateABIInfo(*this);
5170 // If printing assembly, use the recently updated ABI Flags information.
5171 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5173 getTargetStreamer().emitDirectiveModuleSoftFloat();
5175 // If this is not the end of the statement, report an error.
5176 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5177 reportParseError("unexpected token, expected end of statement");
5181 return false; // parseDirectiveModule has finished successfully.
5182 } else if (Option == "hardfloat") {
5183 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5185 // Synchronize the ABI Flags information with the FeatureBits information we
5187 getTargetStreamer().updateABIInfo(*this);
5189 // If printing assembly, use the recently updated ABI Flags information.
5190 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5192 getTargetStreamer().emitDirectiveModuleHardFloat();
5194 // If this is not the end of the statement, report an error.
5195 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5196 reportParseError("unexpected token, expected end of statement");
5200 return false; // parseDirectiveModule has finished successfully.
5202 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5206 /// parseDirectiveModuleFP
5210 bool MipsAsmParser::parseDirectiveModuleFP() {
5211 MCAsmParser &Parser = getParser();
5212 MCAsmLexer &Lexer = getLexer();
5214 if (Lexer.isNot(AsmToken::Equal)) {
5215 reportParseError("unexpected token, expected equals sign '='");
5218 Parser.Lex(); // Eat '=' token.
5220 MipsABIFlagsSection::FpABIKind FpABI;
5221 if (!parseFpABIValue(FpABI, ".module"))
5224 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5225 reportParseError("unexpected token, expected end of statement");
5229 // Synchronize the abiflags information with the FeatureBits information we
5231 getTargetStreamer().updateABIInfo(*this);
5233 // If printing assembly, use the recently updated abiflags information.
5234 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5235 // emitted at the end).
5236 getTargetStreamer().emitDirectiveModuleFP();
5238 Parser.Lex(); // Consume the EndOfStatement.
5242 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5243 StringRef Directive) {
5244 MCAsmParser &Parser = getParser();
5245 MCAsmLexer &Lexer = getLexer();
5246 bool ModuleLevelOptions = Directive == ".module";
5248 if (Lexer.is(AsmToken::Identifier)) {
5249 StringRef Value = Parser.getTok().getString();
5252 if (Value != "xx") {
5253 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5258 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5262 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5263 if (ModuleLevelOptions) {
5264 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5265 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5267 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5268 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5273 if (Lexer.is(AsmToken::Integer)) {
5274 unsigned Value = Parser.getTok().getIntVal();
5277 if (Value != 32 && Value != 64) {
5278 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5284 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5288 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5289 if (ModuleLevelOptions) {
5290 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5291 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5293 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5294 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5297 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5298 if (ModuleLevelOptions) {
5299 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5300 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5302 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5303 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5313 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5314 MCAsmParser &Parser = getParser();
5315 StringRef IDVal = DirectiveID.getString();
5317 if (IDVal == ".cpload")
5318 return parseDirectiveCpLoad(DirectiveID.getLoc());
5319 if (IDVal == ".dword") {
5320 parseDataDirective(8, DirectiveID.getLoc());
5323 if (IDVal == ".ent") {
5324 StringRef SymbolName;
5326 if (Parser.parseIdentifier(SymbolName)) {
5327 reportParseError("expected identifier after .ent");
5331 // There's an undocumented extension that allows an integer to
5332 // follow the name of the procedure which AFAICS is ignored by GAS.
5333 // Example: .ent foo,2
5334 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5335 if (getLexer().isNot(AsmToken::Comma)) {
5336 // Even though we accept this undocumented extension for compatibility
5337 // reasons, the additional integer argument does not actually change
5338 // the behaviour of the '.ent' directive, so we would like to discourage
5339 // its use. We do this by not referring to the extended version in
5340 // error messages which are not directly related to its use.
5341 reportParseError("unexpected token, expected end of statement");
5344 Parser.Lex(); // Eat the comma.
5345 const MCExpr *DummyNumber;
5346 int64_t DummyNumberVal;
5347 // If the user was explicitly trying to use the extended version,
5348 // we still give helpful extension-related error messages.
5349 if (Parser.parseExpression(DummyNumber)) {
5350 reportParseError("expected number after comma");
5353 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5354 reportParseError("expected an absolute expression after comma");
5359 // If this is not the end of the statement, report an error.
5360 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5361 reportParseError("unexpected token, expected end of statement");
5365 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5367 getTargetStreamer().emitDirectiveEnt(*Sym);
5372 if (IDVal == ".end") {
5373 StringRef SymbolName;
5375 if (Parser.parseIdentifier(SymbolName)) {
5376 reportParseError("expected identifier after .end");
5380 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5381 reportParseError("unexpected token, expected end of statement");
5385 if (CurrentFn == nullptr) {
5386 reportParseError(".end used without .ent");
5390 if ((SymbolName != CurrentFn->getName())) {
5391 reportParseError(".end symbol does not match .ent symbol");
5395 getTargetStreamer().emitDirectiveEnd(SymbolName);
5396 CurrentFn = nullptr;
5400 if (IDVal == ".frame") {
5401 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5402 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5403 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5404 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5405 reportParseError("expected stack register");
5409 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5410 if (!StackRegOpnd.isGPRAsmReg()) {
5411 reportParseError(StackRegOpnd.getStartLoc(),
5412 "expected general purpose register");
5415 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5417 if (Parser.getTok().is(AsmToken::Comma))
5420 reportParseError("unexpected token, expected comma");
5424 // Parse the frame size.
5425 const MCExpr *FrameSize;
5426 int64_t FrameSizeVal;
5428 if (Parser.parseExpression(FrameSize)) {
5429 reportParseError("expected frame size value");
5433 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5434 reportParseError("frame size not an absolute expression");
5438 if (Parser.getTok().is(AsmToken::Comma))
5441 reportParseError("unexpected token, expected comma");
5445 // Parse the return register.
5447 ResTy = parseAnyRegister(TmpReg);
5448 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5449 reportParseError("expected return register");
5453 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5454 if (!ReturnRegOpnd.isGPRAsmReg()) {
5455 reportParseError(ReturnRegOpnd.getStartLoc(),
5456 "expected general purpose register");
5460 // If this is not the end of the statement, report an error.
5461 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5462 reportParseError("unexpected token, expected end of statement");
5466 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5467 ReturnRegOpnd.getGPR32Reg());
5471 if (IDVal == ".set") {
5472 return parseDirectiveSet();
5475 if (IDVal == ".mask" || IDVal == ".fmask") {
5476 // .mask bitmask, frame_offset
5477 // bitmask: One bit for each register used.
5478 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5479 // first register is expected to be saved.
5481 // .mask 0x80000000, -4
5482 // .fmask 0x80000000, -4
5485 // Parse the bitmask
5486 const MCExpr *BitMask;
5489 if (Parser.parseExpression(BitMask)) {
5490 reportParseError("expected bitmask value");
5494 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5495 reportParseError("bitmask not an absolute expression");
5499 if (Parser.getTok().is(AsmToken::Comma))
5502 reportParseError("unexpected token, expected comma");
5506 // Parse the frame_offset
5507 const MCExpr *FrameOffset;
5508 int64_t FrameOffsetVal;
5510 if (Parser.parseExpression(FrameOffset)) {
5511 reportParseError("expected frame offset value");
5515 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5516 reportParseError("frame offset not an absolute expression");
5520 // If this is not the end of the statement, report an error.
5521 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5522 reportParseError("unexpected token, expected end of statement");
5526 if (IDVal == ".mask")
5527 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5529 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5533 if (IDVal == ".nan")
5534 return parseDirectiveNaN();
5536 if (IDVal == ".gpword") {
5537 parseDirectiveGpWord();
5541 if (IDVal == ".gpdword") {
5542 parseDirectiveGpDWord();
5546 if (IDVal == ".word") {
5547 parseDataDirective(4, DirectiveID.getLoc());
5551 if (IDVal == ".option")
5552 return parseDirectiveOption();
5554 if (IDVal == ".abicalls") {
5555 getTargetStreamer().emitDirectiveAbiCalls();
5556 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5557 Error(Parser.getTok().getLoc(),
5558 "unexpected token, expected end of statement");
5560 Parser.eatToEndOfStatement();
5565 if (IDVal == ".cpsetup")
5566 return parseDirectiveCPSetup();
5568 if (IDVal == ".module")
5569 return parseDirectiveModule();
5571 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5572 return parseInternalDirectiveReallowModule();
5574 if (IDVal == ".insn")
5575 return parseInsnDirective();
5580 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5581 // If this is not the end of the statement, report an error.
5582 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5583 reportParseError("unexpected token, expected end of statement");
5587 getTargetStreamer().reallowModuleDirective();
5589 getParser().Lex(); // Eat EndOfStatement token.
5593 extern "C" void LLVMInitializeMipsAsmParser() {
5594 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5595 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5596 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5597 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5600 #define GET_REGISTER_MATCHER
5601 #define GET_MATCHER_IMPLEMENTATION
5602 #include "MipsGenAsmMatcher.inc"