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());
949 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
950 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
951 && getMemBase()->isGPRAsmReg();
953 bool isMemWithGRPMM16Base() const {
954 return isMem() && getMemBase()->isMM16AsmReg();
956 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
957 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
958 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
960 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
961 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
962 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
963 && (getMemBase()->getGPR32Reg() == Mips::SP);
965 bool isRegList16() const {
969 int Size = RegList.List->size();
970 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
971 RegList.List->back() != Mips::RA)
974 int PrevReg = *RegList.List->begin();
975 for (int i = 1; i < Size - 1; i++) {
976 int Reg = (*(RegList.List))[i];
977 if ( Reg != PrevReg + 1)
984 bool isInvNum() const { return Kind == k_Immediate; }
985 bool isLSAImm() const {
986 if (!isConstantImm())
988 int64_t Val = getConstantImm();
989 return 1 <= Val && Val <= 4;
991 bool isRegList() const { return Kind == k_RegList; }
992 bool isMovePRegPair() const {
993 if (Kind != k_RegList || RegList.List->size() != 2)
996 unsigned R0 = RegList.List->front();
997 unsigned R1 = RegList.List->back();
999 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1000 (R0 == Mips::A1 && R1 == Mips::A3) ||
1001 (R0 == Mips::A2 && R1 == Mips::A3) ||
1002 (R0 == Mips::A0 && R1 == Mips::S5) ||
1003 (R0 == Mips::A0 && R1 == Mips::S6) ||
1004 (R0 == Mips::A0 && R1 == Mips::A1) ||
1005 (R0 == Mips::A0 && R1 == Mips::A2) ||
1006 (R0 == Mips::A0 && R1 == Mips::A3))
1012 StringRef getToken() const {
1013 assert(Kind == k_Token && "Invalid access!");
1014 return StringRef(Tok.Data, Tok.Length);
1016 bool isRegPair() const { return Kind == k_RegPair; }
1018 unsigned getReg() const override {
1019 // As a special case until we sort out the definition of div/divu, pretend
1020 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1021 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1022 RegIdx.Kind & RegKind_GPR)
1023 return getGPR32Reg(); // FIXME: GPR64 too
1025 assert(Kind == k_PhysRegister && "Invalid access!");
1029 const MCExpr *getImm() const {
1030 assert((Kind == k_Immediate) && "Invalid access!");
1034 int64_t getConstantImm() const {
1035 const MCExpr *Val = getImm();
1036 return static_cast<const MCConstantExpr *>(Val)->getValue();
1039 MipsOperand *getMemBase() const {
1040 assert((Kind == k_Memory) && "Invalid access!");
1044 const MCExpr *getMemOff() const {
1045 assert((Kind == k_Memory) && "Invalid access!");
1049 int64_t getConstantMemOff() const {
1050 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1053 const SmallVectorImpl<unsigned> &getRegList() const {
1054 assert((Kind == k_RegList) && "Invalid access!");
1055 return *(RegList.List);
1058 unsigned getRegPair() const {
1059 assert((Kind == k_RegPair) && "Invalid access!");
1060 return RegIdx.Index;
1063 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1064 MipsAsmParser &Parser) {
1065 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1066 Op->Tok.Data = Str.data();
1067 Op->Tok.Length = Str.size();
1073 /// Create a numeric register (e.g. $1). The exact register remains
1074 /// unresolved until an instruction successfully matches
1075 static std::unique_ptr<MipsOperand>
1076 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1077 SMLoc E, MipsAsmParser &Parser) {
1078 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1079 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1082 /// Create a register that is definitely a GPR.
1083 /// This is typically only used for named registers such as $gp.
1084 static std::unique_ptr<MipsOperand>
1085 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1086 MipsAsmParser &Parser) {
1087 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1090 /// Create a register that is definitely a FGR.
1091 /// This is typically only used for named registers such as $f0.
1092 static std::unique_ptr<MipsOperand>
1093 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1094 MipsAsmParser &Parser) {
1095 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1098 /// Create a register that is definitely a HWReg.
1099 /// This is typically only used for named registers such as $hwr_cpunum.
1100 static std::unique_ptr<MipsOperand>
1101 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1102 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1103 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1106 /// Create a register that is definitely an FCC.
1107 /// This is typically only used for named registers such as $fcc0.
1108 static std::unique_ptr<MipsOperand>
1109 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1110 MipsAsmParser &Parser) {
1111 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1114 /// Create a register that is definitely an ACC.
1115 /// This is typically only used for named registers such as $ac0.
1116 static std::unique_ptr<MipsOperand>
1117 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1118 MipsAsmParser &Parser) {
1119 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1122 /// Create a register that is definitely an MSA128.
1123 /// This is typically only used for named registers such as $w0.
1124 static std::unique_ptr<MipsOperand>
1125 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1126 SMLoc E, MipsAsmParser &Parser) {
1127 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1130 /// Create a register that is definitely an MSACtrl.
1131 /// This is typically only used for named registers such as $msaaccess.
1132 static std::unique_ptr<MipsOperand>
1133 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1134 SMLoc E, MipsAsmParser &Parser) {
1135 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1138 static std::unique_ptr<MipsOperand>
1139 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1140 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1147 static std::unique_ptr<MipsOperand>
1148 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1149 SMLoc E, MipsAsmParser &Parser) {
1150 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1151 Op->Mem.Base = Base.release();
1158 static std::unique_ptr<MipsOperand>
1159 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1160 MipsAsmParser &Parser) {
1161 assert (Regs.size() > 0 && "Empty list not allowed");
1163 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1164 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1165 Op->StartLoc = StartLoc;
1166 Op->EndLoc = EndLoc;
1170 static std::unique_ptr<MipsOperand>
1171 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1172 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1173 Op->RegIdx.Index = RegNo;
1179 bool isGPRAsmReg() const {
1180 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1182 bool isMM16AsmReg() const {
1183 if (!(isRegIdx() && RegIdx.Kind))
1185 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1186 || RegIdx.Index == 16 || RegIdx.Index == 17);
1188 bool isMM16AsmRegZero() const {
1189 if (!(isRegIdx() && RegIdx.Kind))
1191 return (RegIdx.Index == 0 ||
1192 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1193 RegIdx.Index == 17);
1195 bool isMM16AsmRegMoveP() const {
1196 if (!(isRegIdx() && RegIdx.Kind))
1198 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1199 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1201 bool isFGRAsmReg() const {
1202 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1203 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1205 bool isHWRegsAsmReg() const {
1206 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1208 bool isCCRAsmReg() const {
1209 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1211 bool isFCCAsmReg() const {
1212 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1214 if (!AsmParser.hasEightFccRegisters())
1215 return RegIdx.Index == 0;
1216 return RegIdx.Index <= 7;
1218 bool isACCAsmReg() const {
1219 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1221 bool isCOP0AsmReg() const {
1222 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1224 bool isCOP2AsmReg() const {
1225 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1227 bool isCOP3AsmReg() const {
1228 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1230 bool isMSA128AsmReg() const {
1231 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1233 bool isMSACtrlAsmReg() const {
1234 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1237 /// getStartLoc - Get the location of the first token of this operand.
1238 SMLoc getStartLoc() const override { return StartLoc; }
1239 /// getEndLoc - Get the location of the last token of this operand.
1240 SMLoc getEndLoc() const override { return EndLoc; }
1242 virtual ~MipsOperand() {
1250 delete RegList.List;
1251 case k_PhysRegister:
1252 case k_RegisterIndex:
1259 void print(raw_ostream &OS) const override {
1268 Mem.Base->print(OS);
1273 case k_PhysRegister:
1274 OS << "PhysReg<" << PhysReg.Num << ">";
1276 case k_RegisterIndex:
1277 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1284 for (auto Reg : (*RegList.List))
1289 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1293 }; // class MipsOperand
1297 extern const MCInstrDesc MipsInsts[];
1299 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1300 return MipsInsts[Opcode];
1303 static bool hasShortDelaySlot(unsigned Opcode) {
1306 case Mips::JALRS_MM:
1307 case Mips::JALRS16_MM:
1308 case Mips::BGEZALS_MM:
1309 case Mips::BLTZALS_MM:
1316 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1317 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1318 return &SRExpr->getSymbol();
1321 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1322 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1323 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1334 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1335 return getSingleMCSymbol(UExpr->getSubExpr());
1340 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1341 if (isa<MCSymbolRefExpr>(Expr))
1344 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1345 return countMCSymbolRefExpr(BExpr->getLHS()) +
1346 countMCSymbolRefExpr(BExpr->getRHS());
1348 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1349 return countMCSymbolRefExpr(UExpr->getSubExpr());
1354 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1355 SmallVectorImpl<MCInst> &Instructions) {
1356 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1360 if (MCID.isBranch() || MCID.isCall()) {
1361 const unsigned Opcode = Inst.getOpcode();
1371 assert(hasCnMips() && "instruction only valid for octeon cpus");
1378 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1379 Offset = Inst.getOperand(2);
1380 if (!Offset.isImm())
1381 break; // We'll deal with this situation later on when applying fixups.
1382 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1383 return Error(IDLoc, "branch target out of range");
1384 if (OffsetToAlignment(Offset.getImm(),
1385 1LL << (inMicroMipsMode() ? 1 : 2)))
1386 return Error(IDLoc, "branch to misaligned address");
1400 case Mips::BGEZAL_MM:
1401 case Mips::BLTZAL_MM:
1404 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1405 Offset = Inst.getOperand(1);
1406 if (!Offset.isImm())
1407 break; // We'll deal with this situation later on when applying fixups.
1408 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1409 return Error(IDLoc, "branch target out of range");
1410 if (OffsetToAlignment(Offset.getImm(),
1411 1LL << (inMicroMipsMode() ? 1 : 2)))
1412 return Error(IDLoc, "branch to misaligned address");
1414 case Mips::BEQZ16_MM:
1415 case Mips::BEQZC16_MMR6:
1416 case Mips::BNEZ16_MM:
1417 case Mips::BNEZC16_MMR6:
1418 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1419 Offset = Inst.getOperand(1);
1420 if (!Offset.isImm())
1421 break; // We'll deal with this situation later on when applying fixups.
1422 if (!isIntN(8, Offset.getImm()))
1423 return Error(IDLoc, "branch target out of range");
1424 if (OffsetToAlignment(Offset.getImm(), 2LL))
1425 return Error(IDLoc, "branch to misaligned address");
1430 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1431 // We still accept it but it is a normal nop.
1432 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1433 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1434 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1439 const unsigned Opcode = Inst.getOpcode();
1451 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1452 // The offset is handled above
1453 Opnd = Inst.getOperand(1);
1455 return Error(IDLoc, "expected immediate operand kind");
1456 Imm = Opnd.getImm();
1457 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1458 Opcode == Mips::BBIT1 ? 63 : 31))
1459 return Error(IDLoc, "immediate operand value out of range");
1461 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1463 Inst.getOperand(1).setImm(Imm - 32);
1471 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1473 Opnd = Inst.getOperand(3);
1475 return Error(IDLoc, "expected immediate operand kind");
1476 Imm = Opnd.getImm();
1477 if (Imm < 0 || Imm > 31)
1478 return Error(IDLoc, "immediate operand value out of range");
1480 Opnd = Inst.getOperand(2);
1482 return Error(IDLoc, "expected immediate operand kind");
1483 Imm = Opnd.getImm();
1484 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1485 Opcode == Mips::EXTS ? 63 : 31))
1486 return Error(IDLoc, "immediate operand value out of range");
1488 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1489 Inst.getOperand(2).setImm(Imm - 32);
1495 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1496 Opnd = Inst.getOperand(2);
1498 return Error(IDLoc, "expected immediate operand kind");
1499 Imm = Opnd.getImm();
1500 if (!isInt<10>(Imm))
1501 return Error(IDLoc, "immediate operand value out of range");
1506 // This expansion is not in a function called by expandInstruction() because
1507 // the pseudo-instruction doesn't have a distinct opcode.
1508 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1510 warnIfNoMacro(IDLoc);
1512 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1514 // We can do this expansion if there's only 1 symbol in the argument
1516 if (countMCSymbolRefExpr(JalExpr) > 1)
1517 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1519 // FIXME: This is checking the expression can be handled by the later stages
1520 // of the assembler. We ought to leave it to those later stages but
1521 // we can't do that until we stop evaluateRelocExpr() rewriting the
1522 // expressions into non-equivalent forms.
1523 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1525 // FIXME: Add support for label+offset operands (currently causes an error).
1526 // FIXME: Add support for forward-declared local symbols.
1527 // FIXME: Add expansion for when the LargeGOT option is enabled.
1528 if (JalSym->isInSection() || JalSym->isTemporary()) {
1530 // If it's a local symbol and the O32 ABI is being used, we expand to:
1532 // R_(MICRO)MIPS_GOT16 label
1533 // addiu $25, $25, 0
1534 // R_(MICRO)MIPS_LO16 label
1536 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1537 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1540 LwInst.setOpcode(Mips::LW);
1541 LwInst.addOperand(MCOperand::createReg(Mips::T9));
1542 LwInst.addOperand(MCOperand::createReg(Mips::GP));
1543 LwInst.addOperand(MCOperand::createExpr(Got16RelocExpr));
1544 Instructions.push_back(LwInst);
1547 AddiuInst.setOpcode(Mips::ADDiu);
1548 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1549 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1550 AddiuInst.addOperand(MCOperand::createExpr(Lo16RelocExpr));
1551 Instructions.push_back(AddiuInst);
1552 } else if (isABI_N32() || isABI_N64()) {
1553 // If it's a local symbol and the N32/N64 ABIs are being used,
1555 // lw/ld $25, 0($gp)
1556 // R_(MICRO)MIPS_GOT_DISP label
1558 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1561 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1562 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1563 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1564 LoadInst.addOperand(MCOperand::createExpr(GotDispRelocExpr));
1565 Instructions.push_back(LoadInst);
1568 // If it's an external/weak symbol, we expand to:
1569 // lw/ld $25, 0($gp)
1570 // R_(MICRO)MIPS_CALL16 label
1572 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1575 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1576 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1577 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1578 LoadInst.addOperand(MCOperand::createExpr(Call16RelocExpr));
1579 Instructions.push_back(LoadInst);
1583 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1584 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1585 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1587 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1588 // This relocation is supposed to be an optimization hint for the linker
1589 // and is not necessary for correctness.
1594 if (MCID.mayLoad() || MCID.mayStore()) {
1595 // Check the offset of memory operand, if it is a symbol
1596 // reference or immediate we may have to expand instructions.
1597 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1598 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1599 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1600 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1601 MCOperand &Op = Inst.getOperand(i);
1603 int MemOffset = Op.getImm();
1604 if (MemOffset < -32768 || MemOffset > 32767) {
1605 // Offset can't exceed 16bit value.
1606 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1609 } else if (Op.isExpr()) {
1610 const MCExpr *Expr = Op.getExpr();
1611 if (Expr->getKind() == MCExpr::SymbolRef) {
1612 const MCSymbolRefExpr *SR =
1613 static_cast<const MCSymbolRefExpr *>(Expr);
1614 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1616 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1619 } else if (!isEvaluated(Expr)) {
1620 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1628 if (inMicroMipsMode()) {
1629 if (MCID.mayLoad()) {
1630 // Try to create 16-bit GP relative load instruction.
1631 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1632 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1633 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1634 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1635 MCOperand &Op = Inst.getOperand(i);
1637 int MemOffset = Op.getImm();
1638 MCOperand &DstReg = Inst.getOperand(0);
1639 MCOperand &BaseReg = Inst.getOperand(1);
1640 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1641 getContext().getRegisterInfo()->getRegClass(
1642 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1643 (BaseReg.getReg() == Mips::GP ||
1644 BaseReg.getReg() == Mips::GP_64)) {
1646 TmpInst.setLoc(IDLoc);
1647 TmpInst.setOpcode(Mips::LWGP_MM);
1648 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1649 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1650 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1651 Instructions.push_back(TmpInst);
1659 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1664 switch (Inst.getOpcode()) {
1667 case Mips::ADDIUS5_MM:
1668 Opnd = Inst.getOperand(2);
1670 return Error(IDLoc, "expected immediate operand kind");
1671 Imm = Opnd.getImm();
1672 if (Imm < -8 || Imm > 7)
1673 return Error(IDLoc, "immediate operand value out of range");
1675 case Mips::ADDIUSP_MM:
1676 Opnd = Inst.getOperand(0);
1678 return Error(IDLoc, "expected immediate operand kind");
1679 Imm = Opnd.getImm();
1680 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1682 return Error(IDLoc, "immediate operand value out of range");
1684 case Mips::SLL16_MM:
1685 case Mips::SRL16_MM:
1686 Opnd = Inst.getOperand(2);
1688 return Error(IDLoc, "expected immediate operand kind");
1689 Imm = Opnd.getImm();
1690 if (Imm < 1 || Imm > 8)
1691 return Error(IDLoc, "immediate operand value out of range");
1694 Opnd = Inst.getOperand(1);
1696 return Error(IDLoc, "expected immediate operand kind");
1697 Imm = Opnd.getImm();
1698 if (Imm < -1 || Imm > 126)
1699 return Error(IDLoc, "immediate operand value out of range");
1701 case Mips::ADDIUR2_MM:
1702 Opnd = Inst.getOperand(2);
1704 return Error(IDLoc, "expected immediate operand kind");
1705 Imm = Opnd.getImm();
1706 if (!(Imm == 1 || Imm == -1 ||
1707 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1708 return Error(IDLoc, "immediate operand value out of range");
1710 case Mips::ADDIUR1SP_MM:
1711 Opnd = Inst.getOperand(1);
1713 return Error(IDLoc, "expected immediate operand kind");
1714 Imm = Opnd.getImm();
1715 if (OffsetToAlignment(Imm, 4LL))
1716 return Error(IDLoc, "misaligned immediate operand value");
1717 if (Imm < 0 || Imm > 255)
1718 return Error(IDLoc, "immediate operand value out of range");
1720 case Mips::ANDI16_MM:
1721 Opnd = Inst.getOperand(2);
1723 return Error(IDLoc, "expected immediate operand kind");
1724 Imm = Opnd.getImm();
1725 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1726 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1727 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1728 return Error(IDLoc, "immediate operand value out of range");
1730 case Mips::LBU16_MM:
1731 Opnd = Inst.getOperand(2);
1733 return Error(IDLoc, "expected immediate operand kind");
1734 Imm = Opnd.getImm();
1735 if (Imm < -1 || Imm > 14)
1736 return Error(IDLoc, "immediate operand value out of range");
1739 Opnd = Inst.getOperand(2);
1741 return Error(IDLoc, "expected immediate operand kind");
1742 Imm = Opnd.getImm();
1743 if (Imm < 0 || Imm > 15)
1744 return Error(IDLoc, "immediate operand value out of range");
1746 case Mips::LHU16_MM:
1748 Opnd = Inst.getOperand(2);
1750 return Error(IDLoc, "expected immediate operand kind");
1751 Imm = Opnd.getImm();
1752 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1753 return Error(IDLoc, "immediate operand value out of range");
1757 Opnd = Inst.getOperand(2);
1759 return Error(IDLoc, "expected immediate operand kind");
1760 Imm = Opnd.getImm();
1761 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1762 return Error(IDLoc, "immediate operand value out of range");
1766 Opnd = Inst.getOperand(2);
1768 return Error(IDLoc, "expected immediate operand kind");
1769 Imm = Opnd.getImm();
1770 if (!isUInt<5>(Imm))
1771 return Error(IDLoc, "immediate operand value out of range");
1773 case Mips::ADDIUPC_MM:
1774 MCOperand Opnd = Inst.getOperand(1);
1776 return Error(IDLoc, "expected immediate operand kind");
1777 int Imm = Opnd.getImm();
1778 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1779 return Error(IDLoc, "immediate operand value out of range");
1784 if (needsExpansion(Inst)) {
1785 if (expandInstruction(Inst, IDLoc, Instructions))
1788 Instructions.push_back(Inst);
1790 // If this instruction has a delay slot and .set reorder is active,
1791 // emit a NOP after it.
1792 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1793 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1798 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1800 switch (Inst.getOpcode()) {
1801 case Mips::LoadImm32:
1802 case Mips::LoadImm64:
1803 case Mips::LoadAddrImm32:
1804 case Mips::LoadAddrImm64:
1805 case Mips::LoadAddrReg32:
1806 case Mips::LoadAddrReg64:
1807 case Mips::B_MM_Pseudo:
1808 case Mips::B_MMR6_Pseudo:
1811 case Mips::JalOneReg:
1812 case Mips::JalTwoReg:
1823 case Mips::SDivMacro:
1824 case Mips::UDivMacro:
1825 case Mips::DSDivMacro:
1826 case Mips::DUDivMacro:
1835 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1836 SmallVectorImpl<MCInst> &Instructions) {
1837 switch (Inst.getOpcode()) {
1838 default: llvm_unreachable("unimplemented expansion");
1839 case Mips::LoadImm32:
1840 return expandLoadImm(Inst, true, IDLoc, Instructions);
1841 case Mips::LoadImm64:
1842 return expandLoadImm(Inst, false, IDLoc, Instructions);
1843 case Mips::LoadAddrImm32:
1844 case Mips::LoadAddrImm64:
1845 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1846 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1847 "expected immediate operand kind");
1849 return expandLoadAddress(
1850 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1851 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1852 case Mips::LoadAddrReg32:
1853 case Mips::LoadAddrReg64:
1854 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1855 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1856 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1857 "expected immediate operand kind");
1859 return expandLoadAddress(
1860 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1861 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1862 case Mips::B_MM_Pseudo:
1863 case Mips::B_MMR6_Pseudo:
1864 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1867 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1868 case Mips::JalOneReg:
1869 case Mips::JalTwoReg:
1870 return expandJalWithRegs(Inst, IDLoc, Instructions);
1873 return expandBranchImm(Inst, IDLoc, Instructions);
1882 return expandCondBranches(Inst, IDLoc, Instructions);
1883 case Mips::SDivMacro:
1884 return expandDiv(Inst, IDLoc, Instructions, false, true);
1885 case Mips::DSDivMacro:
1886 return expandDiv(Inst, IDLoc, Instructions, true, true);
1887 case Mips::UDivMacro:
1888 return expandDiv(Inst, IDLoc, Instructions, false, false);
1889 case Mips::DUDivMacro:
1890 return expandDiv(Inst, IDLoc, Instructions, true, false);
1892 return expandUlhu(Inst, IDLoc, Instructions);
1894 return expandUlw(Inst, IDLoc, Instructions);
1899 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1900 SmallVectorImpl<MCInst> &Instructions) {
1902 tmpInst.setOpcode(Opcode);
1903 tmpInst.addOperand(MCOperand::createReg(Reg0));
1904 tmpInst.addOperand(Op1);
1905 tmpInst.setLoc(IDLoc);
1906 Instructions.push_back(tmpInst);
1909 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1910 SmallVectorImpl<MCInst> &Instructions) {
1911 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1914 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1915 SmallVectorImpl<MCInst> &Instructions) {
1916 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1919 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1920 SmallVectorImpl<MCInst> &Instructions) {
1922 tmpInst.setOpcode(Opcode);
1923 tmpInst.addOperand(MCOperand::createImm(Imm1));
1924 tmpInst.addOperand(MCOperand::createImm(Imm2));
1925 tmpInst.setLoc(IDLoc);
1926 Instructions.push_back(tmpInst);
1929 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1930 SmallVectorImpl<MCInst> &Instructions) {
1932 tmpInst.setOpcode(Opcode);
1933 tmpInst.addOperand(MCOperand::createReg(Reg0));
1934 tmpInst.setLoc(IDLoc);
1935 Instructions.push_back(tmpInst);
1938 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1939 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1941 tmpInst.setOpcode(Opcode);
1942 tmpInst.addOperand(MCOperand::createReg(Reg0));
1943 tmpInst.addOperand(MCOperand::createReg(Reg1));
1944 tmpInst.addOperand(Op2);
1945 tmpInst.setLoc(IDLoc);
1946 Instructions.push_back(tmpInst);
1949 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1950 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1951 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1955 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1956 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1957 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1961 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1962 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1963 if (ShiftAmount >= 32) {
1964 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1969 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1971 } // end anonymous namespace.
1973 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1974 SmallVectorImpl<MCInst> &Instructions) {
1975 // Create a JALR instruction which is going to replace the pseudo-JAL.
1977 JalrInst.setLoc(IDLoc);
1978 const MCOperand FirstRegOp = Inst.getOperand(0);
1979 const unsigned Opcode = Inst.getOpcode();
1981 if (Opcode == Mips::JalOneReg) {
1982 // jal $rs => jalr $rs
1983 if (inMicroMipsMode()) {
1984 JalrInst.setOpcode(Mips::JALR16_MM);
1985 JalrInst.addOperand(FirstRegOp);
1987 JalrInst.setOpcode(Mips::JALR);
1988 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1989 JalrInst.addOperand(FirstRegOp);
1991 } else if (Opcode == Mips::JalTwoReg) {
1992 // jal $rd, $rs => jalr $rd, $rs
1993 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1994 JalrInst.addOperand(FirstRegOp);
1995 const MCOperand SecondRegOp = Inst.getOperand(1);
1996 JalrInst.addOperand(SecondRegOp);
1998 Instructions.push_back(JalrInst);
2000 // If .set reorder is active, emit a NOP after it.
2001 if (AssemblerOptions.back()->isReorder()) {
2002 // This is a 32-bit NOP because these 2 pseudo-instructions
2003 // do not have a short delay slot.
2005 NopInst.setOpcode(Mips::SLL);
2006 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2007 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2008 NopInst.addOperand(MCOperand::createImm(0));
2009 Instructions.push_back(NopInst);
2015 /// Can the value be represented by a unsigned N-bit value and a shift left?
2016 template<unsigned N>
2017 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2018 unsigned BitNum = findFirstSet(x);
2020 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2023 /// Load (or add) an immediate into a register.
2025 /// @param ImmValue The immediate to load.
2026 /// @param DstReg The register that will hold the immediate.
2027 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2028 /// for a simple initialization.
2029 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2030 /// @param IsAddress True if the immediate represents an address. False if it
2032 /// @param IDLoc Location of the immediate in the source file.
2033 /// @param Instructions The instructions emitted by this expansion.
2034 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2035 unsigned SrcReg, bool Is32BitImm,
2036 bool IsAddress, SMLoc IDLoc,
2037 SmallVectorImpl<MCInst> &Instructions) {
2038 if (!Is32BitImm && !isGP64bit()) {
2039 Error(IDLoc, "instruction requires a 64-bit architecture");
2044 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2045 // Sign extend up to 64-bit so that the predicates match the hardware
2046 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2048 ImmValue = SignExtend64<32>(ImmValue);
2050 Error(IDLoc, "instruction requires a 32-bit immediate");
2055 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2056 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2058 bool UseSrcReg = false;
2059 if (SrcReg != Mips::NoRegister)
2062 unsigned TmpReg = DstReg;
2063 if (UseSrcReg && (DstReg == SrcReg)) {
2064 // At this point we need AT to perform the expansions and we exit if it is
2066 unsigned ATReg = getATReg(IDLoc);
2072 if (isInt<16>(ImmValue)) {
2076 // This doesn't quite follow the usual ABI expectations for N32 but matches
2077 // traditional assembler behaviour. N32 would normally use addiu for both
2078 // integers and addresses.
2079 if (IsAddress && !Is32BitImm) {
2080 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2084 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2088 if (isUInt<16>(ImmValue)) {
2089 unsigned TmpReg = DstReg;
2090 if (SrcReg == DstReg) {
2091 TmpReg = getATReg(IDLoc);
2096 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2098 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2102 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2103 warnIfNoMacro(IDLoc);
2105 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2106 uint16_t Bits15To0 = ImmValue & 0xffff;
2108 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2109 // Traditional behaviour seems to special case this particular value. It's
2110 // not clear why other masks are handled differently.
2111 if (ImmValue == 0xffffffff) {
2112 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2113 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2115 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2119 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2121 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2122 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2124 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2126 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2130 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2132 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2134 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2138 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2140 Error(IDLoc, "instruction requires a 32-bit immediate");
2144 // Traditionally, these immediates are shifted as little as possible and as
2145 // such we align the most significant bit to bit 15 of our temporary.
2146 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2147 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2148 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2149 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2150 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2151 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2154 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2159 warnIfNoMacro(IDLoc);
2161 // The remaining case is packed with a sequence of dsll and ori with zeros
2162 // being omitted and any neighbouring dsll's being coalesced.
2163 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2165 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2166 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2167 IDLoc, Instructions))
2170 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2171 // skip it and defer the shift to the next chunk.
2172 unsigned ShiftCarriedForwards = 16;
2173 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2174 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2176 if (ImmChunk != 0) {
2177 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2179 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2180 ShiftCarriedForwards = 0;
2183 ShiftCarriedForwards += 16;
2185 ShiftCarriedForwards -= 16;
2187 // Finish any remaining shifts left by trailing zeros.
2188 if (ShiftCarriedForwards)
2189 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2193 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2198 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2199 SmallVectorImpl<MCInst> &Instructions) {
2200 const MCOperand &ImmOp = Inst.getOperand(1);
2201 assert(ImmOp.isImm() && "expected immediate operand kind");
2202 const MCOperand &DstRegOp = Inst.getOperand(0);
2203 assert(DstRegOp.isReg() && "expected register operand kind");
2205 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2206 Is32BitImm, false, IDLoc, Instructions))
2212 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2213 const MCOperand &Offset,
2214 bool Is32BitAddress, SMLoc IDLoc,
2215 SmallVectorImpl<MCInst> &Instructions) {
2216 // la can't produce a usable address when addresses are 64-bit.
2217 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2218 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2219 // We currently can't do this because we depend on the equality
2220 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2221 Error(IDLoc, "la used to load 64-bit address");
2222 // Continue as if we had 'dla' instead.
2223 Is32BitAddress = false;
2226 // dla requires 64-bit addresses.
2227 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2228 Error(IDLoc, "instruction requires a 64-bit architecture");
2232 if (!Offset.isImm())
2233 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2234 Is32BitAddress, IDLoc, Instructions);
2236 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2237 IDLoc, Instructions);
2240 bool MipsAsmParser::loadAndAddSymbolAddress(
2241 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2242 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2243 warnIfNoMacro(IDLoc);
2245 // FIXME: The way we're handling symbols right now prevents simple expressions
2246 // like foo+8. We'll be able to fix this once our unary operators (%hi
2247 // and similar) are treated as operators rather than as fixup types.
2248 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2249 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2250 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2251 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2252 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2254 bool UseSrcReg = SrcReg != Mips::NoRegister;
2256 // This is the 64-bit symbol address expansion.
2257 if (ABI.ArePtrs64bit() && isGP64bit()) {
2258 // We always need AT for the 64-bit expansion.
2259 // If it is not available we exit.
2260 unsigned ATReg = getATReg(IDLoc);
2264 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2265 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2266 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2267 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2269 if (UseSrcReg && (DstReg == SrcReg)) {
2270 // If $rs is the same as $rd:
2271 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2272 // daddiu $at, $at, %higher(sym)
2273 // dsll $at, $at, 16
2274 // daddiu $at, $at, %hi(sym)
2275 // dsll $at, $at, 16
2276 // daddiu $at, $at, %lo(sym)
2277 // daddu $rd, $at, $rd
2278 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2280 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2281 IDLoc, Instructions);
2282 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2283 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2285 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2286 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2288 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2293 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2294 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2295 // lui $at, %hi(sym)
2296 // daddiu $rd, $rd, %higher(sym)
2297 // daddiu $at, $at, %lo(sym)
2298 // dsll32 $rd, $rd, 0
2299 // daddu $rd, $rd, $at
2300 // (daddu $rd, $rd, $rs)
2301 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2303 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2305 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2306 IDLoc, Instructions);
2307 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2309 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2310 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2312 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2317 // And now, the 32-bit symbol address expansion:
2318 // If $rs is the same as $rd:
2319 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2320 // ori $at, $at, %lo(sym)
2321 // addu $rd, $at, $rd
2322 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2323 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2324 // ori $rd, $rd, %lo(sym)
2325 // (addu $rd, $rd, $rs)
2326 unsigned TmpReg = DstReg;
2327 if (UseSrcReg && (DstReg == SrcReg)) {
2328 // If $rs is the same as $rd, we need to use AT.
2329 // If it is not available we exit.
2330 unsigned ATReg = getATReg(IDLoc);
2336 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2337 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2341 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2343 assert(DstReg == TmpReg);
2348 bool MipsAsmParser::expandUncondBranchMMPseudo(
2349 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2350 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2351 "unexpected number of operands");
2353 MCOperand Offset = Inst.getOperand(0);
2354 if (Offset.isExpr()) {
2356 Inst.setOpcode(Mips::BEQ_MM);
2357 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2358 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2359 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2361 assert(Offset.isImm() && "expected immediate operand kind");
2362 if (isIntN(11, Offset.getImm())) {
2363 // If offset fits into 11 bits then this instruction becomes microMIPS
2364 // 16-bit unconditional branch instruction.
2365 if (inMicroMipsMode())
2366 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2368 if (!isIntN(17, Offset.getImm()))
2369 Error(IDLoc, "branch target out of range");
2370 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2371 Error(IDLoc, "branch to misaligned address");
2373 Inst.setOpcode(Mips::BEQ_MM);
2374 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2375 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2376 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2379 Instructions.push_back(Inst);
2381 // If .set reorder is active and branch instruction has a delay slot,
2382 // emit a NOP after it.
2383 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2384 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2385 createNop(true, IDLoc, Instructions);
2390 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2391 SmallVectorImpl<MCInst> &Instructions) {
2392 const MCOperand &DstRegOp = Inst.getOperand(0);
2393 assert(DstRegOp.isReg() && "expected register operand kind");
2395 const MCOperand &ImmOp = Inst.getOperand(1);
2396 assert(ImmOp.isImm() && "expected immediate operand kind");
2398 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2399 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2401 unsigned OpCode = 0;
2402 switch(Inst.getOpcode()) {
2410 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2414 int64_t ImmValue = ImmOp.getImm();
2415 if (ImmValue == 0) {
2417 BranchInst.setOpcode(OpCode);
2418 BranchInst.addOperand(DstRegOp);
2419 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2420 BranchInst.addOperand(MemOffsetOp);
2421 Instructions.push_back(BranchInst);
2423 warnIfNoMacro(IDLoc);
2425 unsigned ATReg = getATReg(IDLoc);
2429 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2430 IDLoc, Instructions))
2434 BranchInst.setOpcode(OpCode);
2435 BranchInst.addOperand(DstRegOp);
2436 BranchInst.addOperand(MCOperand::createReg(ATReg));
2437 BranchInst.addOperand(MemOffsetOp);
2438 Instructions.push_back(BranchInst);
2443 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2444 SmallVectorImpl<MCInst> &Instructions,
2445 bool isLoad, bool isImmOpnd) {
2447 unsigned ImmOffset, HiOffset, LoOffset;
2448 const MCExpr *ExprOffset;
2450 // 1st operand is either the source or destination register.
2451 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2452 unsigned RegOpNum = Inst.getOperand(0).getReg();
2453 // 2nd operand is the base register.
2454 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2455 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2456 // 3rd operand is either an immediate or expression.
2458 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2459 ImmOffset = Inst.getOperand(2).getImm();
2460 LoOffset = ImmOffset & 0x0000ffff;
2461 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2462 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2463 if (LoOffset & 0x8000)
2466 ExprOffset = Inst.getOperand(2).getExpr();
2467 // All instructions will have the same location.
2468 TempInst.setLoc(IDLoc);
2469 // These are some of the types of expansions we perform here:
2470 // 1) lw $8, sym => lui $8, %hi(sym)
2471 // lw $8, %lo(sym)($8)
2472 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2474 // lw $8, %lo(offset)($9)
2475 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2477 // lw $8, %lo(offset)($at)
2478 // 4) sw $8, sym => lui $at, %hi(sym)
2479 // sw $8, %lo(sym)($at)
2480 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2482 // sw $8, %lo(offset)($at)
2483 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2484 // ldc1 $f0, %lo(sym)($at)
2486 // For load instructions we can use the destination register as a temporary
2487 // if base and dst are different (examples 1 and 2) and if the base register
2488 // is general purpose otherwise we must use $at (example 6) and error if it's
2489 // not available. For stores we must use $at (examples 4 and 5) because we
2490 // must not clobber the source register setting up the offset.
2491 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2492 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2493 unsigned RegClassIDOp0 =
2494 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2495 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2496 (RegClassIDOp0 == Mips::GPR64RegClassID);
2497 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2498 TmpRegNum = RegOpNum;
2500 // At this point we need AT to perform the expansions and we exit if it is
2502 TmpRegNum = getATReg(IDLoc);
2507 TempInst.setOpcode(Mips::LUi);
2508 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2510 TempInst.addOperand(MCOperand::createImm(HiOffset));
2512 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2513 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2515 // Add the instruction to the list.
2516 Instructions.push_back(TempInst);
2517 // Prepare TempInst for next instruction.
2519 // Add temp register to base.
2520 if (BaseRegNum != Mips::ZERO) {
2521 TempInst.setOpcode(Mips::ADDu);
2522 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2523 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2524 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2525 Instructions.push_back(TempInst);
2528 // And finally, create original instruction with low part
2529 // of offset and new base.
2530 TempInst.setOpcode(Inst.getOpcode());
2531 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2532 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2534 TempInst.addOperand(MCOperand::createImm(LoOffset));
2536 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2537 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2539 Instructions.push_back(TempInst);
2544 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2545 SmallVectorImpl<MCInst> &Instructions) {
2546 unsigned OpNum = Inst.getNumOperands();
2547 unsigned Opcode = Inst.getOpcode();
2548 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2550 assert (Inst.getOperand(OpNum - 1).isImm() &&
2551 Inst.getOperand(OpNum - 2).isReg() &&
2552 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2554 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2555 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2556 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2557 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2558 // It can be implemented as SWM16 or LWM16 instruction.
2559 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2561 Inst.setOpcode(NewOpcode);
2562 Instructions.push_back(Inst);
2566 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2567 SmallVectorImpl<MCInst> &Instructions) {
2568 unsigned PseudoOpcode = Inst.getOpcode();
2569 unsigned SrcReg = Inst.getOperand(0).getReg();
2570 unsigned TrgReg = Inst.getOperand(1).getReg();
2571 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2573 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2574 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2576 switch (PseudoOpcode) {
2579 AcceptsEquality = false;
2580 ReverseOrderSLT = false;
2581 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2582 ZeroSrcOpcode = Mips::BGTZ;
2583 ZeroTrgOpcode = Mips::BLTZ;
2587 AcceptsEquality = true;
2588 ReverseOrderSLT = true;
2589 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2590 ZeroSrcOpcode = Mips::BGEZ;
2591 ZeroTrgOpcode = Mips::BLEZ;
2595 AcceptsEquality = true;
2596 ReverseOrderSLT = false;
2597 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2598 ZeroSrcOpcode = Mips::BLEZ;
2599 ZeroTrgOpcode = Mips::BGEZ;
2603 AcceptsEquality = false;
2604 ReverseOrderSLT = true;
2605 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2606 ZeroSrcOpcode = Mips::BLTZ;
2607 ZeroTrgOpcode = Mips::BGTZ;
2610 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2614 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2615 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2616 if (IsSrcRegZero && IsTrgRegZero) {
2617 // FIXME: All of these Opcode-specific if's are needed for compatibility
2618 // with GAS' behaviour. However, they may not generate the most efficient
2619 // code in some circumstances.
2620 if (PseudoOpcode == Mips::BLT) {
2621 BranchInst.setOpcode(Mips::BLTZ);
2622 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2623 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2624 Instructions.push_back(BranchInst);
2627 if (PseudoOpcode == Mips::BLE) {
2628 BranchInst.setOpcode(Mips::BLEZ);
2629 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2630 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2631 Instructions.push_back(BranchInst);
2632 Warning(IDLoc, "branch is always taken");
2635 if (PseudoOpcode == Mips::BGE) {
2636 BranchInst.setOpcode(Mips::BGEZ);
2637 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2638 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2639 Instructions.push_back(BranchInst);
2640 Warning(IDLoc, "branch is always taken");
2643 if (PseudoOpcode == Mips::BGT) {
2644 BranchInst.setOpcode(Mips::BGTZ);
2645 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2646 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2647 Instructions.push_back(BranchInst);
2650 if (PseudoOpcode == Mips::BGTU) {
2651 BranchInst.setOpcode(Mips::BNE);
2652 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2653 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2654 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2655 Instructions.push_back(BranchInst);
2658 if (AcceptsEquality) {
2659 // If both registers are $0 and the pseudo-branch accepts equality, it
2660 // will always be taken, so we emit an unconditional branch.
2661 BranchInst.setOpcode(Mips::BEQ);
2662 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2663 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2664 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2665 Instructions.push_back(BranchInst);
2666 Warning(IDLoc, "branch is always taken");
2669 // If both registers are $0 and the pseudo-branch does not accept
2670 // equality, it will never be taken, so we don't have to emit anything.
2673 if (IsSrcRegZero || IsTrgRegZero) {
2674 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2675 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2676 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2677 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2678 // the pseudo-branch will never be taken, so we don't emit anything.
2679 // This only applies to unsigned pseudo-branches.
2682 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2683 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2684 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2685 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2686 // the pseudo-branch will always be taken, so we emit an unconditional
2688 // This only applies to unsigned pseudo-branches.
2689 BranchInst.setOpcode(Mips::BEQ);
2690 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2691 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2692 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2693 Instructions.push_back(BranchInst);
2694 Warning(IDLoc, "branch is always taken");
2698 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2699 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2700 // the pseudo-branch will be taken only when the non-zero register is
2701 // different from 0, so we emit a BNEZ.
2703 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2704 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2705 // the pseudo-branch will be taken only when the non-zero register is
2706 // equal to 0, so we emit a BEQZ.
2708 // Because only BLEU and BGEU branch on equality, we can use the
2709 // AcceptsEquality variable to decide when to emit the BEQZ.
2710 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2711 BranchInst.addOperand(
2712 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2713 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2714 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2715 Instructions.push_back(BranchInst);
2718 // If we have a signed pseudo-branch and one of the registers is $0,
2719 // we can use an appropriate compare-to-zero branch. We select which one
2720 // to use in the switch statement above.
2721 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2722 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2723 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2724 Instructions.push_back(BranchInst);
2728 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2729 // expansions. If it is not available, we return.
2730 unsigned ATRegNum = getATReg(IDLoc);
2734 warnIfNoMacro(IDLoc);
2736 // SLT fits well with 2 of our 4 pseudo-branches:
2737 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2738 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2739 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2740 // This is accomplished by using a BNEZ with the result of the SLT.
2742 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2743 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2744 // Because only BGE and BLE branch on equality, we can use the
2745 // AcceptsEquality variable to decide when to emit the BEQZ.
2746 // Note that the order of the SLT arguments doesn't change between
2749 // The same applies to the unsigned variants, except that SLTu is used
2752 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2753 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2754 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2755 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2756 Instructions.push_back(SetInst);
2758 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2759 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2760 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2761 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2762 Instructions.push_back(BranchInst);
2766 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2767 SmallVectorImpl<MCInst> &Instructions,
2768 const bool IsMips64, const bool Signed) {
2769 if (hasMips32r6()) {
2770 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2774 warnIfNoMacro(IDLoc);
2776 const MCOperand &RsRegOp = Inst.getOperand(0);
2777 assert(RsRegOp.isReg() && "expected register operand kind");
2778 unsigned RsReg = RsRegOp.getReg();
2780 const MCOperand &RtRegOp = Inst.getOperand(1);
2781 assert(RtRegOp.isReg() && "expected register operand kind");
2782 unsigned RtReg = RtRegOp.getReg();
2787 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2788 ZeroReg = Mips::ZERO_64;
2790 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2791 ZeroReg = Mips::ZERO;
2794 bool UseTraps = useTraps();
2796 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2797 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2798 Warning(IDLoc, "dividing zero by zero");
2800 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2802 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2806 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2810 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2815 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2816 Warning(IDLoc, "division by zero");
2819 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2823 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2828 // FIXME: The values for these two BranchTarget variables may be different in
2829 // micromips. These magic numbers need to be removed.
2830 unsigned BranchTargetNoTraps;
2831 unsigned BranchTarget;
2834 BranchTarget = IsMips64 ? 12 : 8;
2835 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2837 BranchTarget = IsMips64 ? 20 : 16;
2838 BranchTargetNoTraps = 8;
2839 // Branch to the li instruction.
2840 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2844 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2847 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2850 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2854 unsigned ATReg = getATReg(IDLoc);
2858 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2860 // Branch to the mflo instruction.
2861 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2862 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2863 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2865 // Branch to the mflo instruction.
2866 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2867 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2871 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2873 // Branch to the mflo instruction.
2874 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2875 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2876 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2878 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2882 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2883 SmallVectorImpl<MCInst> &Instructions) {
2884 if (hasMips32r6() || hasMips64r6()) {
2885 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2889 warnIfNoMacro(IDLoc);
2891 const MCOperand &DstRegOp = Inst.getOperand(0);
2892 assert(DstRegOp.isReg() && "expected register operand kind");
2894 const MCOperand &SrcRegOp = Inst.getOperand(1);
2895 assert(SrcRegOp.isReg() && "expected register operand kind");
2897 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2898 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2900 unsigned DstReg = DstRegOp.getReg();
2901 unsigned SrcReg = SrcRegOp.getReg();
2902 int64_t OffsetValue = OffsetImmOp.getImm();
2904 // NOTE: We always need AT for ULHU, as it is always used as the source
2905 // register for one of the LBu's.
2906 unsigned ATReg = getATReg(IDLoc);
2910 // When the value of offset+1 does not fit in 16 bits, we have to load the
2911 // offset in AT, (D)ADDu the original source register (if there was one), and
2912 // then use AT as the source register for the 2 generated LBu's.
2913 bool LoadedOffsetInAT = false;
2914 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2915 LoadedOffsetInAT = true;
2917 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2918 true, IDLoc, Instructions))
2921 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2922 // because it will make our output more similar to GAS'. For example,
2923 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2924 // instead of just an "ori $1, $9, 32768".
2925 // NOTE: If there is no source register specified in the ULHU, the parser
2926 // will interpret it as $0.
2927 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2928 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2931 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2932 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2933 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2935 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2937 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2938 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2940 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2941 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2944 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2947 TmpInst.setOpcode(Mips::LBu);
2948 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2949 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2950 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2951 Instructions.push_back(TmpInst);
2954 TmpInst.setOpcode(Mips::LBu);
2955 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2956 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2957 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2958 Instructions.push_back(TmpInst);
2961 TmpInst.setOpcode(Mips::SLL);
2962 TmpInst.addOperand(MCOperand::createReg(SllReg));
2963 TmpInst.addOperand(MCOperand::createReg(SllReg));
2964 TmpInst.addOperand(MCOperand::createImm(8));
2965 Instructions.push_back(TmpInst);
2968 TmpInst.setOpcode(Mips::OR);
2969 TmpInst.addOperand(MCOperand::createReg(DstReg));
2970 TmpInst.addOperand(MCOperand::createReg(DstReg));
2971 TmpInst.addOperand(MCOperand::createReg(ATReg));
2972 Instructions.push_back(TmpInst);
2977 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2978 SmallVectorImpl<MCInst> &Instructions) {
2979 if (hasMips32r6() || hasMips64r6()) {
2980 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2984 const MCOperand &DstRegOp = Inst.getOperand(0);
2985 assert(DstRegOp.isReg() && "expected register operand kind");
2987 const MCOperand &SrcRegOp = Inst.getOperand(1);
2988 assert(SrcRegOp.isReg() && "expected register operand kind");
2990 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2991 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2993 unsigned SrcReg = SrcRegOp.getReg();
2994 int64_t OffsetValue = OffsetImmOp.getImm();
2997 // When the value of offset+3 does not fit in 16 bits, we have to load the
2998 // offset in AT, (D)ADDu the original source register (if there was one), and
2999 // then use AT as the source register for the generated LWL and LWR.
3000 bool LoadedOffsetInAT = false;
3001 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3002 ATReg = getATReg(IDLoc);
3005 LoadedOffsetInAT = true;
3007 warnIfNoMacro(IDLoc);
3009 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3010 true, IDLoc, Instructions))
3013 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3014 // because it will make our output more similar to GAS'. For example,
3015 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3016 // instead of just an "ori $1, $9, 32768".
3017 // NOTE: If there is no source register specified in the ULW, the parser
3018 // will interpret it as $0.
3019 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3020 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3023 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3024 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3026 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3027 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3029 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3030 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3033 MCInst LeftLoadInst;
3034 LeftLoadInst.setOpcode(Mips::LWL);
3035 LeftLoadInst.addOperand(DstRegOp);
3036 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3037 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3038 Instructions.push_back(LeftLoadInst);
3040 MCInst RightLoadInst;
3041 RightLoadInst.setOpcode(Mips::LWR);
3042 RightLoadInst.addOperand(DstRegOp);
3043 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3044 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3045 Instructions.push_back(RightLoadInst);
3050 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3051 SmallVectorImpl<MCInst> &Instructions) {
3053 if (hasShortDelaySlot) {
3054 NopInst.setOpcode(Mips::MOVE16_MM);
3055 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3056 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3058 NopInst.setOpcode(Mips::SLL);
3059 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3060 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3061 NopInst.addOperand(MCOperand::createImm(0));
3063 Instructions.push_back(NopInst);
3066 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3067 unsigned TrgReg, bool Is64Bit,
3068 SmallVectorImpl<MCInst> &Instructions) {
3069 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3073 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3074 // As described by the Mips32r2 spec, the registers Rd and Rs for
3075 // jalr.hb must be different.
3076 unsigned Opcode = Inst.getOpcode();
3078 if (Opcode == Mips::JALR_HB &&
3079 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3080 return Match_RequiresDifferentSrcAndDst;
3082 return Match_Success;
3085 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3086 OperandVector &Operands,
3088 uint64_t &ErrorInfo,
3089 bool MatchingInlineAsm) {
3092 SmallVector<MCInst, 8> Instructions;
3093 unsigned MatchResult =
3094 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3096 switch (MatchResult) {
3097 case Match_Success: {
3098 if (processInstruction(Inst, IDLoc, Instructions))
3100 for (unsigned i = 0; i < Instructions.size(); i++)
3101 Out.EmitInstruction(Instructions[i], STI);
3104 case Match_MissingFeature:
3105 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3107 case Match_InvalidOperand: {
3108 SMLoc ErrorLoc = IDLoc;
3109 if (ErrorInfo != ~0ULL) {
3110 if (ErrorInfo >= Operands.size())
3111 return Error(IDLoc, "too few operands for instruction");
3113 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3114 if (ErrorLoc == SMLoc())
3118 return Error(ErrorLoc, "invalid operand for instruction");
3120 case Match_MnemonicFail:
3121 return Error(IDLoc, "invalid instruction");
3122 case Match_RequiresDifferentSrcAndDst:
3123 return Error(IDLoc, "source and destination must be different");
3126 llvm_unreachable("Implement any new match types added!");
3129 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3130 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3131 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3132 ") without \".set noat\"");
3135 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3136 if (!AssemblerOptions.back()->isMacro())
3137 Warning(Loc, "macro instruction expanded into multiple instructions");
3141 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3142 SMRange Range, bool ShowColors) {
3143 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3144 Range, SMFixIt(Range, FixMsg),
3148 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3151 CC = StringSwitch<unsigned>(Name)
3187 if (!(isABI_N32() || isABI_N64()))
3190 if (12 <= CC && CC <= 15) {
3191 // Name is one of t4-t7
3192 AsmToken RegTok = getLexer().peekTok();
3193 SMRange RegRange = RegTok.getLocRange();
3195 StringRef FixedName = StringSwitch<StringRef>(Name)
3201 assert(FixedName != "" && "Register name is not one of t4-t7.");
3203 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3204 "Did you mean $" + FixedName + "?", RegRange);
3207 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3208 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3209 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3210 if (8 <= CC && CC <= 11)
3214 CC = StringSwitch<unsigned>(Name)
3226 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3229 CC = StringSwitch<unsigned>(Name)
3230 .Case("hwr_cpunum", 0)
3231 .Case("hwr_synci_step", 1)
3233 .Case("hwr_ccres", 3)
3234 .Case("hwr_ulr", 29)
3240 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3242 if (Name[0] == 'f') {
3243 StringRef NumString = Name.substr(1);
3245 if (NumString.getAsInteger(10, IntVal))
3246 return -1; // This is not an integer.
3247 if (IntVal > 31) // Maximum index for fpu register.
3254 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3256 if (Name.startswith("fcc")) {
3257 StringRef NumString = Name.substr(3);
3259 if (NumString.getAsInteger(10, IntVal))
3260 return -1; // This is not an integer.
3261 if (IntVal > 7) // There are only 8 fcc registers.
3268 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3270 if (Name.startswith("ac")) {
3271 StringRef NumString = Name.substr(2);
3273 if (NumString.getAsInteger(10, IntVal))
3274 return -1; // This is not an integer.
3275 if (IntVal > 3) // There are only 3 acc registers.
3282 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3285 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3294 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3297 CC = StringSwitch<unsigned>(Name)
3300 .Case("msaaccess", 2)
3302 .Case("msamodify", 4)
3303 .Case("msarequest", 5)
3305 .Case("msaunmap", 7)
3311 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3312 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3314 reportParseError(Loc,
3315 "pseudo-instruction requires $at, which is not available");
3318 unsigned AT = getReg(
3319 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3323 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3324 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3327 unsigned MipsAsmParser::getGPR(int RegNo) {
3328 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3332 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3334 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3337 return getReg(RegClass, RegNum);
3340 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3341 MCAsmParser &Parser = getParser();
3342 DEBUG(dbgs() << "parseOperand\n");
3344 // Check if the current operand has a custom associated parser, if so, try to
3345 // custom parse the operand, or fallback to the general approach.
3346 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3347 if (ResTy == MatchOperand_Success)
3349 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3350 // there was a match, but an error occurred, in which case, just return that
3351 // the operand parsing failed.
3352 if (ResTy == MatchOperand_ParseFail)
3355 DEBUG(dbgs() << ".. Generic Parser\n");
3357 switch (getLexer().getKind()) {
3359 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3361 case AsmToken::Dollar: {
3362 // Parse the register.
3363 SMLoc S = Parser.getTok().getLoc();
3365 // Almost all registers have been parsed by custom parsers. There is only
3366 // one exception to this. $zero (and it's alias $0) will reach this point
3367 // for div, divu, and similar instructions because it is not an operand
3368 // to the instruction definition but an explicit register. Special case
3369 // this situation for now.
3370 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3373 // Maybe it is a symbol reference.
3374 StringRef Identifier;
3375 if (Parser.parseIdentifier(Identifier))
3378 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3379 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3380 // Otherwise create a symbol reference.
3382 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3384 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3387 // Else drop to expression parsing.
3388 case AsmToken::LParen:
3389 case AsmToken::Minus:
3390 case AsmToken::Plus:
3391 case AsmToken::Integer:
3392 case AsmToken::Tilde:
3393 case AsmToken::String: {
3394 DEBUG(dbgs() << ".. generic integer\n");
3395 OperandMatchResultTy ResTy = parseImm(Operands);
3396 return ResTy != MatchOperand_Success;
3398 case AsmToken::Percent: {
3399 // It is a symbol reference or constant expression.
3400 const MCExpr *IdVal;
3401 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3402 if (parseRelocOperand(IdVal))
3405 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3407 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3409 } // case AsmToken::Percent
3410 } // switch(getLexer().getKind())
3414 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3415 StringRef RelocStr) {
3417 // Check the type of the expression.
3418 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3419 // It's a constant, evaluate reloc value.
3421 switch (getVariantKind(RelocStr)) {
3422 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3423 // Get the 1st 16-bits.
3424 Val = MCE->getValue() & 0xffff;
3426 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3427 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3428 // 16 bits being negative.
3429 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3431 case MCSymbolRefExpr::VK_Mips_HIGHER:
3432 // Get the 3rd 16-bits.
3433 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3435 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3436 // Get the 4th 16-bits.
3437 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3440 report_fatal_error("unsupported reloc value");
3442 return MCConstantExpr::create(Val, getContext());
3445 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3446 // It's a symbol, create a symbolic expression from the symbol.
3447 const MCSymbol *Symbol = &MSRE->getSymbol();
3448 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3449 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3453 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3454 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3456 // Try to create target expression.
3457 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3458 return MipsMCExpr::create(VK, Expr, getContext());
3460 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3461 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3462 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3466 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3467 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3468 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3471 // Just return the original expression.
3475 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3477 switch (Expr->getKind()) {
3478 case MCExpr::Constant:
3480 case MCExpr::SymbolRef:
3481 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3482 case MCExpr::Binary:
3483 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3484 if (!isEvaluated(BE->getLHS()))
3486 return isEvaluated(BE->getRHS());
3489 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3490 case MCExpr::Target:
3496 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3497 MCAsmParser &Parser = getParser();
3498 Parser.Lex(); // Eat the % token.
3499 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3500 if (Tok.isNot(AsmToken::Identifier))
3503 std::string Str = Tok.getIdentifier();
3505 Parser.Lex(); // Eat the identifier.
3506 // Now make an expression from the rest of the operand.
3507 const MCExpr *IdVal;
3510 if (getLexer().getKind() == AsmToken::LParen) {
3512 Parser.Lex(); // Eat the '(' token.
3513 if (getLexer().getKind() == AsmToken::Percent) {
3514 Parser.Lex(); // Eat the % token.
3515 const AsmToken &nextTok = Parser.getTok();
3516 if (nextTok.isNot(AsmToken::Identifier))
3519 Str += nextTok.getIdentifier();
3520 Parser.Lex(); // Eat the identifier.
3521 if (getLexer().getKind() != AsmToken::LParen)
3526 if (getParser().parseParenExpression(IdVal, EndLoc))
3529 while (getLexer().getKind() == AsmToken::RParen)
3530 Parser.Lex(); // Eat the ')' token.
3533 return true; // Parenthesis must follow the relocation operand.
3535 Res = evaluateRelocExpr(IdVal, Str);
3539 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3541 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3542 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3543 if (ResTy == MatchOperand_Success) {
3544 assert(Operands.size() == 1);
3545 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3546 StartLoc = Operand.getStartLoc();
3547 EndLoc = Operand.getEndLoc();
3549 // AFAIK, we only support numeric registers and named GPR's in CFI
3551 // Don't worry about eating tokens before failing. Using an unrecognised
3552 // register is a parse error.
3553 if (Operand.isGPRAsmReg()) {
3554 // Resolve to GPR32 or GPR64 appropriately.
3555 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3558 return (RegNo == (unsigned)-1);
3561 assert(Operands.size() == 0);
3562 return (RegNo == (unsigned)-1);
3565 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3566 MCAsmParser &Parser = getParser();
3569 unsigned NumOfLParen = 0;
3571 while (getLexer().getKind() == AsmToken::LParen) {
3576 switch (getLexer().getKind()) {
3579 case AsmToken::Identifier:
3580 case AsmToken::LParen:
3581 case AsmToken::Integer:
3582 case AsmToken::Minus:
3583 case AsmToken::Plus:
3585 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3587 Result = (getParser().parseExpression(Res));
3588 while (getLexer().getKind() == AsmToken::RParen)
3591 case AsmToken::Percent:
3592 Result = parseRelocOperand(Res);
3597 MipsAsmParser::OperandMatchResultTy
3598 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3599 MCAsmParser &Parser = getParser();
3600 DEBUG(dbgs() << "parseMemOperand\n");
3601 const MCExpr *IdVal = nullptr;
3603 bool isParenExpr = false;
3604 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3605 // First operand is the offset.
3606 S = Parser.getTok().getLoc();
3608 if (getLexer().getKind() == AsmToken::LParen) {
3613 if (getLexer().getKind() != AsmToken::Dollar) {
3614 if (parseMemOffset(IdVal, isParenExpr))
3615 return MatchOperand_ParseFail;
3617 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3618 if (Tok.isNot(AsmToken::LParen)) {
3619 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3620 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3622 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3623 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3624 return MatchOperand_Success;
3626 if (Tok.is(AsmToken::EndOfStatement)) {
3628 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3630 // Zero register assumed, add a memory operand with ZERO as its base.
3631 // "Base" will be managed by k_Memory.
3632 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3635 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3636 return MatchOperand_Success;
3638 Error(Parser.getTok().getLoc(), "'(' expected");
3639 return MatchOperand_ParseFail;
3642 Parser.Lex(); // Eat the '(' token.
3645 Res = parseAnyRegister(Operands);
3646 if (Res != MatchOperand_Success)
3649 if (Parser.getTok().isNot(AsmToken::RParen)) {
3650 Error(Parser.getTok().getLoc(), "')' expected");
3651 return MatchOperand_ParseFail;
3654 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3656 Parser.Lex(); // Eat the ')' token.
3659 IdVal = MCConstantExpr::create(0, getContext());
3661 // Replace the register operand with the memory operand.
3662 std::unique_ptr<MipsOperand> op(
3663 static_cast<MipsOperand *>(Operands.back().release()));
3664 // Remove the register from the operands.
3665 // "op" will be managed by k_Memory.
3666 Operands.pop_back();
3667 // Add the memory operand.
3668 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3670 if (IdVal->evaluateAsAbsolute(Imm))
3671 IdVal = MCConstantExpr::create(Imm, getContext());
3672 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3673 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3677 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3678 return MatchOperand_Success;
3681 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3682 MCAsmParser &Parser = getParser();
3683 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3685 SMLoc S = Parser.getTok().getLoc();
3687 if (Sym->isVariable())
3688 Expr = Sym->getVariableValue();
3691 if (Expr->getKind() == MCExpr::SymbolRef) {
3692 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3693 StringRef DefSymbol = Ref->getSymbol().getName();
3694 if (DefSymbol.startswith("$")) {
3695 OperandMatchResultTy ResTy =
3696 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3697 if (ResTy == MatchOperand_Success) {
3700 } else if (ResTy == MatchOperand_ParseFail)
3701 llvm_unreachable("Should never ParseFail");
3704 } else if (Expr->getKind() == MCExpr::Constant) {
3706 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3708 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3715 MipsAsmParser::OperandMatchResultTy
3716 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3717 StringRef Identifier,
3719 int Index = matchCPURegisterName(Identifier);
3721 Operands.push_back(MipsOperand::createGPRReg(
3722 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3723 return MatchOperand_Success;
3726 Index = matchHWRegsRegisterName(Identifier);
3728 Operands.push_back(MipsOperand::createHWRegsReg(
3729 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3730 return MatchOperand_Success;
3733 Index = matchFPURegisterName(Identifier);
3735 Operands.push_back(MipsOperand::createFGRReg(
3736 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3737 return MatchOperand_Success;
3740 Index = matchFCCRegisterName(Identifier);
3742 Operands.push_back(MipsOperand::createFCCReg(
3743 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3744 return MatchOperand_Success;
3747 Index = matchACRegisterName(Identifier);
3749 Operands.push_back(MipsOperand::createACCReg(
3750 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3751 return MatchOperand_Success;
3754 Index = matchMSA128RegisterName(Identifier);
3756 Operands.push_back(MipsOperand::createMSA128Reg(
3757 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3758 return MatchOperand_Success;
3761 Index = matchMSA128CtrlRegisterName(Identifier);
3763 Operands.push_back(MipsOperand::createMSACtrlReg(
3764 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3765 return MatchOperand_Success;
3768 return MatchOperand_NoMatch;
3771 MipsAsmParser::OperandMatchResultTy
3772 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3773 MCAsmParser &Parser = getParser();
3774 auto Token = Parser.getLexer().peekTok(false);
3776 if (Token.is(AsmToken::Identifier)) {
3777 DEBUG(dbgs() << ".. identifier\n");
3778 StringRef Identifier = Token.getIdentifier();
3779 OperandMatchResultTy ResTy =
3780 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3782 } else if (Token.is(AsmToken::Integer)) {
3783 DEBUG(dbgs() << ".. integer\n");
3784 Operands.push_back(MipsOperand::createNumericReg(
3785 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3787 return MatchOperand_Success;
3790 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3792 return MatchOperand_NoMatch;
3795 MipsAsmParser::OperandMatchResultTy
3796 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3797 MCAsmParser &Parser = getParser();
3798 DEBUG(dbgs() << "parseAnyRegister\n");
3800 auto Token = Parser.getTok();
3802 SMLoc S = Token.getLoc();
3804 if (Token.isNot(AsmToken::Dollar)) {
3805 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3806 if (Token.is(AsmToken::Identifier)) {
3807 if (searchSymbolAlias(Operands))
3808 return MatchOperand_Success;
3810 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3811 return MatchOperand_NoMatch;
3813 DEBUG(dbgs() << ".. $\n");
3815 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3816 if (ResTy == MatchOperand_Success) {
3818 Parser.Lex(); // identifier
3823 MipsAsmParser::OperandMatchResultTy
3824 MipsAsmParser::parseImm(OperandVector &Operands) {
3825 MCAsmParser &Parser = getParser();
3826 switch (getLexer().getKind()) {
3828 return MatchOperand_NoMatch;
3829 case AsmToken::LParen:
3830 case AsmToken::Minus:
3831 case AsmToken::Plus:
3832 case AsmToken::Integer:
3833 case AsmToken::Tilde:
3834 case AsmToken::String:
3838 const MCExpr *IdVal;
3839 SMLoc S = Parser.getTok().getLoc();
3840 if (getParser().parseExpression(IdVal))
3841 return MatchOperand_ParseFail;
3843 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3844 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3845 return MatchOperand_Success;
3848 MipsAsmParser::OperandMatchResultTy
3849 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3850 MCAsmParser &Parser = getParser();
3851 DEBUG(dbgs() << "parseJumpTarget\n");
3853 SMLoc S = getLexer().getLoc();
3855 // Integers and expressions are acceptable
3856 OperandMatchResultTy ResTy = parseImm(Operands);
3857 if (ResTy != MatchOperand_NoMatch)
3860 // Registers are a valid target and have priority over symbols.
3861 ResTy = parseAnyRegister(Operands);
3862 if (ResTy != MatchOperand_NoMatch)
3865 const MCExpr *Expr = nullptr;
3866 if (Parser.parseExpression(Expr)) {
3867 // We have no way of knowing if a symbol was consumed so we must ParseFail
3868 return MatchOperand_ParseFail;
3871 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3872 return MatchOperand_Success;
3875 MipsAsmParser::OperandMatchResultTy
3876 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3877 MCAsmParser &Parser = getParser();
3878 const MCExpr *IdVal;
3879 // If the first token is '$' we may have register operand.
3880 if (Parser.getTok().is(AsmToken::Dollar))
3881 return MatchOperand_NoMatch;
3882 SMLoc S = Parser.getTok().getLoc();
3883 if (getParser().parseExpression(IdVal))
3884 return MatchOperand_ParseFail;
3885 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3886 assert(MCE && "Unexpected MCExpr type.");
3887 int64_t Val = MCE->getValue();
3888 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3889 Operands.push_back(MipsOperand::CreateImm(
3890 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3891 return MatchOperand_Success;
3894 MipsAsmParser::OperandMatchResultTy
3895 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3896 MCAsmParser &Parser = getParser();
3897 switch (getLexer().getKind()) {
3899 return MatchOperand_NoMatch;
3900 case AsmToken::LParen:
3901 case AsmToken::Plus:
3902 case AsmToken::Minus:
3903 case AsmToken::Integer:
3908 SMLoc S = Parser.getTok().getLoc();
3910 if (getParser().parseExpression(Expr))
3911 return MatchOperand_ParseFail;
3914 if (!Expr->evaluateAsAbsolute(Val)) {
3915 Error(S, "expected immediate value");
3916 return MatchOperand_ParseFail;
3919 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3920 // and because the CPU always adds one to the immediate field, the allowed
3921 // range becomes 1..4. We'll only check the range here and will deal
3922 // with the addition/subtraction when actually decoding/encoding
3924 if (Val < 1 || Val > 4) {
3925 Error(S, "immediate not in range (1..4)");
3926 return MatchOperand_ParseFail;
3930 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3931 return MatchOperand_Success;
3934 MipsAsmParser::OperandMatchResultTy
3935 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3936 MCAsmParser &Parser = getParser();
3937 SmallVector<unsigned, 10> Regs;
3939 unsigned PrevReg = Mips::NoRegister;
3940 bool RegRange = false;
3941 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3943 if (Parser.getTok().isNot(AsmToken::Dollar))
3944 return MatchOperand_ParseFail;
3946 SMLoc S = Parser.getTok().getLoc();
3947 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3948 SMLoc E = getLexer().getLoc();
3949 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3950 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3952 // Remove last register operand because registers from register range
3953 // should be inserted first.
3954 if (RegNo == Mips::RA) {
3955 Regs.push_back(RegNo);
3957 unsigned TmpReg = PrevReg + 1;
3958 while (TmpReg <= RegNo) {
3959 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3960 Error(E, "invalid register operand");
3961 return MatchOperand_ParseFail;
3965 Regs.push_back(TmpReg++);
3971 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3972 (RegNo != Mips::RA)) {
3973 Error(E, "$16 or $31 expected");
3974 return MatchOperand_ParseFail;
3975 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3976 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3977 Error(E, "invalid register operand");
3978 return MatchOperand_ParseFail;
3979 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3980 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3981 Error(E, "consecutive register numbers expected");
3982 return MatchOperand_ParseFail;
3985 Regs.push_back(RegNo);
3988 if (Parser.getTok().is(AsmToken::Minus))
3991 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3992 !Parser.getTok().isNot(AsmToken::Comma)) {
3993 Error(E, "',' or '-' expected");
3994 return MatchOperand_ParseFail;
3997 Lex(); // Consume comma or minus
3998 if (Parser.getTok().isNot(AsmToken::Dollar))
4004 SMLoc E = Parser.getTok().getLoc();
4005 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4006 parseMemOperand(Operands);
4007 return MatchOperand_Success;
4010 MipsAsmParser::OperandMatchResultTy
4011 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4012 MCAsmParser &Parser = getParser();
4014 SMLoc S = Parser.getTok().getLoc();
4015 if (parseAnyRegister(Operands) != MatchOperand_Success)
4016 return MatchOperand_ParseFail;
4018 SMLoc E = Parser.getTok().getLoc();
4019 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4020 unsigned Reg = Op.getGPR32Reg();
4021 Operands.pop_back();
4022 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4023 return MatchOperand_Success;
4026 MipsAsmParser::OperandMatchResultTy
4027 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4028 MCAsmParser &Parser = getParser();
4029 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4030 SmallVector<unsigned, 10> Regs;
4032 if (Parser.getTok().isNot(AsmToken::Dollar))
4033 return MatchOperand_ParseFail;
4035 SMLoc S = Parser.getTok().getLoc();
4037 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4038 return MatchOperand_ParseFail;
4040 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4041 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4042 Regs.push_back(RegNo);
4044 SMLoc E = Parser.getTok().getLoc();
4045 if (Parser.getTok().isNot(AsmToken::Comma)) {
4046 Error(E, "',' expected");
4047 return MatchOperand_ParseFail;
4053 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4054 return MatchOperand_ParseFail;
4056 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4057 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4058 Regs.push_back(RegNo);
4060 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4062 return MatchOperand_Success;
4065 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4067 MCSymbolRefExpr::VariantKind VK =
4068 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4069 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4070 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4071 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4072 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4073 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4074 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4075 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4076 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4077 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4078 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4079 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4080 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4081 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4082 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4083 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4084 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4085 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4086 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4087 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4088 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4089 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4090 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4091 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4092 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4093 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4094 .Default(MCSymbolRefExpr::VK_None);
4096 assert(VK != MCSymbolRefExpr::VK_None);
4101 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4103 /// ::= '(', register, ')'
4104 /// handle it before we iterate so we don't get tripped up by the lack of
4106 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4107 MCAsmParser &Parser = getParser();
4108 if (getLexer().is(AsmToken::LParen)) {
4110 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4112 if (parseOperand(Operands, Name)) {
4113 SMLoc Loc = getLexer().getLoc();
4114 Parser.eatToEndOfStatement();
4115 return Error(Loc, "unexpected token in argument list");
4117 if (Parser.getTok().isNot(AsmToken::RParen)) {
4118 SMLoc Loc = getLexer().getLoc();
4119 Parser.eatToEndOfStatement();
4120 return Error(Loc, "unexpected token, expected ')'");
4123 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4129 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4130 /// either one of these.
4131 /// ::= '[', register, ']'
4132 /// ::= '[', integer, ']'
4133 /// handle it before we iterate so we don't get tripped up by the lack of
4135 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4136 OperandVector &Operands) {
4137 MCAsmParser &Parser = getParser();
4138 if (getLexer().is(AsmToken::LBrac)) {
4140 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4142 if (parseOperand(Operands, Name)) {
4143 SMLoc Loc = getLexer().getLoc();
4144 Parser.eatToEndOfStatement();
4145 return Error(Loc, "unexpected token in argument list");
4147 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4148 SMLoc Loc = getLexer().getLoc();
4149 Parser.eatToEndOfStatement();
4150 return Error(Loc, "unexpected token, expected ']'");
4153 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4159 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4160 SMLoc NameLoc, OperandVector &Operands) {
4161 MCAsmParser &Parser = getParser();
4162 DEBUG(dbgs() << "ParseInstruction\n");
4164 // We have reached first instruction, module directive are now forbidden.
4165 getTargetStreamer().forbidModuleDirective();
4167 // Check if we have valid mnemonic
4168 if (!mnemonicIsValid(Name, 0)) {
4169 Parser.eatToEndOfStatement();
4170 return Error(NameLoc, "unknown instruction");
4172 // First operand in MCInst is instruction mnemonic.
4173 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4175 // Read the remaining operands.
4176 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4177 // Read the first operand.
4178 if (parseOperand(Operands, Name)) {
4179 SMLoc Loc = getLexer().getLoc();
4180 Parser.eatToEndOfStatement();
4181 return Error(Loc, "unexpected token in argument list");
4183 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4185 // AFAIK, parenthesis suffixes are never on the first operand
4187 while (getLexer().is(AsmToken::Comma)) {
4188 Parser.Lex(); // Eat the comma.
4189 // Parse and remember the operand.
4190 if (parseOperand(Operands, Name)) {
4191 SMLoc Loc = getLexer().getLoc();
4192 Parser.eatToEndOfStatement();
4193 return Error(Loc, "unexpected token in argument list");
4195 // Parse bracket and parenthesis suffixes before we iterate
4196 if (getLexer().is(AsmToken::LBrac)) {
4197 if (parseBracketSuffix(Name, Operands))
4199 } else if (getLexer().is(AsmToken::LParen) &&
4200 parseParenSuffix(Name, Operands))
4204 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4205 SMLoc Loc = getLexer().getLoc();
4206 Parser.eatToEndOfStatement();
4207 return Error(Loc, "unexpected token in argument list");
4209 Parser.Lex(); // Consume the EndOfStatement.
4213 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4214 MCAsmParser &Parser = getParser();
4215 SMLoc Loc = getLexer().getLoc();
4216 Parser.eatToEndOfStatement();
4217 return Error(Loc, ErrorMsg);
4220 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4221 return Error(Loc, ErrorMsg);
4224 bool MipsAsmParser::parseSetNoAtDirective() {
4225 MCAsmParser &Parser = getParser();
4226 // Line should look like: ".set noat".
4228 // Set the $at register to $0.
4229 AssemblerOptions.back()->setATRegIndex(0);
4231 Parser.Lex(); // Eat "noat".
4233 // If this is not the end of the statement, report an error.
4234 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4235 reportParseError("unexpected token, expected end of statement");
4239 getTargetStreamer().emitDirectiveSetNoAt();
4240 Parser.Lex(); // Consume the EndOfStatement.
4244 bool MipsAsmParser::parseSetAtDirective() {
4245 // Line can be: ".set at", which sets $at to $1
4246 // or ".set at=$reg", which sets $at to $reg.
4247 MCAsmParser &Parser = getParser();
4248 Parser.Lex(); // Eat "at".
4250 if (getLexer().is(AsmToken::EndOfStatement)) {
4251 // No register was specified, so we set $at to $1.
4252 AssemblerOptions.back()->setATRegIndex(1);
4254 getTargetStreamer().emitDirectiveSetAt();
4255 Parser.Lex(); // Consume the EndOfStatement.
4259 if (getLexer().isNot(AsmToken::Equal)) {
4260 reportParseError("unexpected token, expected equals sign");
4263 Parser.Lex(); // Eat "=".
4265 if (getLexer().isNot(AsmToken::Dollar)) {
4266 if (getLexer().is(AsmToken::EndOfStatement)) {
4267 reportParseError("no register specified");
4270 reportParseError("unexpected token, expected dollar sign '$'");
4274 Parser.Lex(); // Eat "$".
4276 // Find out what "reg" is.
4278 const AsmToken &Reg = Parser.getTok();
4279 if (Reg.is(AsmToken::Identifier)) {
4280 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4281 } else if (Reg.is(AsmToken::Integer)) {
4282 AtRegNo = Reg.getIntVal();
4284 reportParseError("unexpected token, expected identifier or integer");
4288 // Check if $reg is a valid register. If it is, set $at to $reg.
4289 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4290 reportParseError("invalid register");
4293 Parser.Lex(); // Eat "reg".
4295 // If this is not the end of the statement, report an error.
4296 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4297 reportParseError("unexpected token, expected end of statement");
4301 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4303 Parser.Lex(); // Consume the EndOfStatement.
4307 bool MipsAsmParser::parseSetReorderDirective() {
4308 MCAsmParser &Parser = getParser();
4310 // If this is not the end of the statement, report an error.
4311 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4312 reportParseError("unexpected token, expected end of statement");
4315 AssemblerOptions.back()->setReorder();
4316 getTargetStreamer().emitDirectiveSetReorder();
4317 Parser.Lex(); // Consume the EndOfStatement.
4321 bool MipsAsmParser::parseSetNoReorderDirective() {
4322 MCAsmParser &Parser = getParser();
4324 // If this is not the end of the statement, report an error.
4325 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4326 reportParseError("unexpected token, expected end of statement");
4329 AssemblerOptions.back()->setNoReorder();
4330 getTargetStreamer().emitDirectiveSetNoReorder();
4331 Parser.Lex(); // Consume the EndOfStatement.
4335 bool MipsAsmParser::parseSetMacroDirective() {
4336 MCAsmParser &Parser = getParser();
4338 // If this is not the end of the statement, report an error.
4339 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4340 reportParseError("unexpected token, expected end of statement");
4343 AssemblerOptions.back()->setMacro();
4344 getTargetStreamer().emitDirectiveSetMacro();
4345 Parser.Lex(); // Consume the EndOfStatement.
4349 bool MipsAsmParser::parseSetNoMacroDirective() {
4350 MCAsmParser &Parser = getParser();
4352 // If this is not the end of the statement, report an error.
4353 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4354 reportParseError("unexpected token, expected end of statement");
4357 if (AssemblerOptions.back()->isReorder()) {
4358 reportParseError("`noreorder' must be set before `nomacro'");
4361 AssemblerOptions.back()->setNoMacro();
4362 getTargetStreamer().emitDirectiveSetNoMacro();
4363 Parser.Lex(); // Consume the EndOfStatement.
4367 bool MipsAsmParser::parseSetMsaDirective() {
4368 MCAsmParser &Parser = getParser();
4371 // If this is not the end of the statement, report an error.
4372 if (getLexer().isNot(AsmToken::EndOfStatement))
4373 return reportParseError("unexpected token, expected end of statement");
4375 setFeatureBits(Mips::FeatureMSA, "msa");
4376 getTargetStreamer().emitDirectiveSetMsa();
4380 bool MipsAsmParser::parseSetNoMsaDirective() {
4381 MCAsmParser &Parser = getParser();
4384 // If this is not the end of the statement, report an error.
4385 if (getLexer().isNot(AsmToken::EndOfStatement))
4386 return reportParseError("unexpected token, expected end of statement");
4388 clearFeatureBits(Mips::FeatureMSA, "msa");
4389 getTargetStreamer().emitDirectiveSetNoMsa();
4393 bool MipsAsmParser::parseSetNoDspDirective() {
4394 MCAsmParser &Parser = getParser();
4395 Parser.Lex(); // Eat "nodsp".
4397 // If this is not the end of the statement, report an error.
4398 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4399 reportParseError("unexpected token, expected end of statement");
4403 clearFeatureBits(Mips::FeatureDSP, "dsp");
4404 getTargetStreamer().emitDirectiveSetNoDsp();
4408 bool MipsAsmParser::parseSetMips16Directive() {
4409 MCAsmParser &Parser = getParser();
4410 Parser.Lex(); // Eat "mips16".
4412 // If this is not the end of the statement, report an error.
4413 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4414 reportParseError("unexpected token, expected end of statement");
4418 setFeatureBits(Mips::FeatureMips16, "mips16");
4419 getTargetStreamer().emitDirectiveSetMips16();
4420 Parser.Lex(); // Consume the EndOfStatement.
4424 bool MipsAsmParser::parseSetNoMips16Directive() {
4425 MCAsmParser &Parser = getParser();
4426 Parser.Lex(); // Eat "nomips16".
4428 // If this is not the end of the statement, report an error.
4429 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4430 reportParseError("unexpected token, expected end of statement");
4434 clearFeatureBits(Mips::FeatureMips16, "mips16");
4435 getTargetStreamer().emitDirectiveSetNoMips16();
4436 Parser.Lex(); // Consume the EndOfStatement.
4440 bool MipsAsmParser::parseSetFpDirective() {
4441 MCAsmParser &Parser = getParser();
4442 MipsABIFlagsSection::FpABIKind FpAbiVal;
4443 // Line can be: .set fp=32
4446 Parser.Lex(); // Eat fp token
4447 AsmToken Tok = Parser.getTok();
4448 if (Tok.isNot(AsmToken::Equal)) {
4449 reportParseError("unexpected token, expected equals sign '='");
4452 Parser.Lex(); // Eat '=' token.
4453 Tok = Parser.getTok();
4455 if (!parseFpABIValue(FpAbiVal, ".set"))
4458 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4459 reportParseError("unexpected token, expected end of statement");
4462 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4463 Parser.Lex(); // Consume the EndOfStatement.
4467 bool MipsAsmParser::parseSetOddSPRegDirective() {
4468 MCAsmParser &Parser = getParser();
4470 Parser.Lex(); // Eat "oddspreg".
4471 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4472 reportParseError("unexpected token, expected end of statement");
4476 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4477 getTargetStreamer().emitDirectiveSetOddSPReg();
4481 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4482 MCAsmParser &Parser = getParser();
4484 Parser.Lex(); // Eat "nooddspreg".
4485 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4486 reportParseError("unexpected token, expected end of statement");
4490 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4491 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4495 bool MipsAsmParser::parseSetPopDirective() {
4496 MCAsmParser &Parser = getParser();
4497 SMLoc Loc = getLexer().getLoc();
4500 if (getLexer().isNot(AsmToken::EndOfStatement))
4501 return reportParseError("unexpected token, expected end of statement");
4503 // Always keep an element on the options "stack" to prevent the user
4504 // from changing the initial options. This is how we remember them.
4505 if (AssemblerOptions.size() == 2)
4506 return reportParseError(Loc, ".set pop with no .set push");
4508 AssemblerOptions.pop_back();
4509 setAvailableFeatures(
4510 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4511 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4513 getTargetStreamer().emitDirectiveSetPop();
4517 bool MipsAsmParser::parseSetPushDirective() {
4518 MCAsmParser &Parser = getParser();
4520 if (getLexer().isNot(AsmToken::EndOfStatement))
4521 return reportParseError("unexpected token, expected end of statement");
4523 // Create a copy of the current assembler options environment and push it.
4524 AssemblerOptions.push_back(
4525 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4527 getTargetStreamer().emitDirectiveSetPush();
4531 bool MipsAsmParser::parseSetSoftFloatDirective() {
4532 MCAsmParser &Parser = getParser();
4534 if (getLexer().isNot(AsmToken::EndOfStatement))
4535 return reportParseError("unexpected token, expected end of statement");
4537 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4538 getTargetStreamer().emitDirectiveSetSoftFloat();
4542 bool MipsAsmParser::parseSetHardFloatDirective() {
4543 MCAsmParser &Parser = getParser();
4545 if (getLexer().isNot(AsmToken::EndOfStatement))
4546 return reportParseError("unexpected token, expected end of statement");
4548 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4549 getTargetStreamer().emitDirectiveSetHardFloat();
4553 bool MipsAsmParser::parseSetAssignment() {
4555 const MCExpr *Value;
4556 MCAsmParser &Parser = getParser();
4558 if (Parser.parseIdentifier(Name))
4559 reportParseError("expected identifier after .set");
4561 if (getLexer().isNot(AsmToken::Comma))
4562 return reportParseError("unexpected token, expected comma");
4565 if (Parser.parseExpression(Value))
4566 return reportParseError("expected valid expression after comma");
4568 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4569 Sym->setVariableValue(Value);
4574 bool MipsAsmParser::parseSetMips0Directive() {
4575 MCAsmParser &Parser = getParser();
4577 if (getLexer().isNot(AsmToken::EndOfStatement))
4578 return reportParseError("unexpected token, expected end of statement");
4580 // Reset assembler options to their initial values.
4581 setAvailableFeatures(
4582 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4583 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4584 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4586 getTargetStreamer().emitDirectiveSetMips0();
4590 bool MipsAsmParser::parseSetArchDirective() {
4591 MCAsmParser &Parser = getParser();
4593 if (getLexer().isNot(AsmToken::Equal))
4594 return reportParseError("unexpected token, expected equals sign");
4598 if (Parser.parseIdentifier(Arch))
4599 return reportParseError("expected arch identifier");
4601 StringRef ArchFeatureName =
4602 StringSwitch<StringRef>(Arch)
4603 .Case("mips1", "mips1")
4604 .Case("mips2", "mips2")
4605 .Case("mips3", "mips3")
4606 .Case("mips4", "mips4")
4607 .Case("mips5", "mips5")
4608 .Case("mips32", "mips32")
4609 .Case("mips32r2", "mips32r2")
4610 .Case("mips32r3", "mips32r3")
4611 .Case("mips32r5", "mips32r5")
4612 .Case("mips32r6", "mips32r6")
4613 .Case("mips64", "mips64")
4614 .Case("mips64r2", "mips64r2")
4615 .Case("mips64r3", "mips64r3")
4616 .Case("mips64r5", "mips64r5")
4617 .Case("mips64r6", "mips64r6")
4618 .Case("cnmips", "cnmips")
4619 .Case("r4000", "mips3") // This is an implementation of Mips3.
4622 if (ArchFeatureName.empty())
4623 return reportParseError("unsupported architecture");
4625 selectArch(ArchFeatureName);
4626 getTargetStreamer().emitDirectiveSetArch(Arch);
4630 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4631 MCAsmParser &Parser = getParser();
4633 if (getLexer().isNot(AsmToken::EndOfStatement))
4634 return reportParseError("unexpected token, expected end of statement");
4638 llvm_unreachable("Unimplemented feature");
4639 case Mips::FeatureDSP:
4640 setFeatureBits(Mips::FeatureDSP, "dsp");
4641 getTargetStreamer().emitDirectiveSetDsp();
4643 case Mips::FeatureMicroMips:
4644 getTargetStreamer().emitDirectiveSetMicroMips();
4646 case Mips::FeatureMips1:
4647 selectArch("mips1");
4648 getTargetStreamer().emitDirectiveSetMips1();
4650 case Mips::FeatureMips2:
4651 selectArch("mips2");
4652 getTargetStreamer().emitDirectiveSetMips2();
4654 case Mips::FeatureMips3:
4655 selectArch("mips3");
4656 getTargetStreamer().emitDirectiveSetMips3();
4658 case Mips::FeatureMips4:
4659 selectArch("mips4");
4660 getTargetStreamer().emitDirectiveSetMips4();
4662 case Mips::FeatureMips5:
4663 selectArch("mips5");
4664 getTargetStreamer().emitDirectiveSetMips5();
4666 case Mips::FeatureMips32:
4667 selectArch("mips32");
4668 getTargetStreamer().emitDirectiveSetMips32();
4670 case Mips::FeatureMips32r2:
4671 selectArch("mips32r2");
4672 getTargetStreamer().emitDirectiveSetMips32R2();
4674 case Mips::FeatureMips32r3:
4675 selectArch("mips32r3");
4676 getTargetStreamer().emitDirectiveSetMips32R3();
4678 case Mips::FeatureMips32r5:
4679 selectArch("mips32r5");
4680 getTargetStreamer().emitDirectiveSetMips32R5();
4682 case Mips::FeatureMips32r6:
4683 selectArch("mips32r6");
4684 getTargetStreamer().emitDirectiveSetMips32R6();
4686 case Mips::FeatureMips64:
4687 selectArch("mips64");
4688 getTargetStreamer().emitDirectiveSetMips64();
4690 case Mips::FeatureMips64r2:
4691 selectArch("mips64r2");
4692 getTargetStreamer().emitDirectiveSetMips64R2();
4694 case Mips::FeatureMips64r3:
4695 selectArch("mips64r3");
4696 getTargetStreamer().emitDirectiveSetMips64R3();
4698 case Mips::FeatureMips64r5:
4699 selectArch("mips64r5");
4700 getTargetStreamer().emitDirectiveSetMips64R5();
4702 case Mips::FeatureMips64r6:
4703 selectArch("mips64r6");
4704 getTargetStreamer().emitDirectiveSetMips64R6();
4710 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4711 MCAsmParser &Parser = getParser();
4712 if (getLexer().isNot(AsmToken::Comma)) {
4713 SMLoc Loc = getLexer().getLoc();
4714 Parser.eatToEndOfStatement();
4715 return Error(Loc, ErrorStr);
4718 Parser.Lex(); // Eat the comma.
4722 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4723 if (AssemblerOptions.back()->isReorder())
4724 Warning(Loc, ".cpload should be inside a noreorder section");
4726 if (inMips16Mode()) {
4727 reportParseError(".cpload is not supported in Mips16 mode");
4731 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4732 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4733 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4734 reportParseError("expected register containing function address");
4738 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4739 if (!RegOpnd.isGPRAsmReg()) {
4740 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4744 // If this is not the end of the statement, report an error.
4745 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4746 reportParseError("unexpected token, expected end of statement");
4750 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4754 bool MipsAsmParser::parseDirectiveCPSetup() {
4755 MCAsmParser &Parser = getParser();
4758 bool SaveIsReg = true;
4760 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4761 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4762 if (ResTy == MatchOperand_NoMatch) {
4763 reportParseError("expected register containing function address");
4764 Parser.eatToEndOfStatement();
4768 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4769 if (!FuncRegOpnd.isGPRAsmReg()) {
4770 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4771 Parser.eatToEndOfStatement();
4775 FuncReg = FuncRegOpnd.getGPR32Reg();
4778 if (!eatComma("unexpected token, expected comma"))
4781 ResTy = parseAnyRegister(TmpReg);
4782 if (ResTy == MatchOperand_NoMatch) {
4783 const AsmToken &Tok = Parser.getTok();
4784 if (Tok.is(AsmToken::Integer)) {
4785 Save = Tok.getIntVal();
4789 reportParseError("expected save register or stack offset");
4790 Parser.eatToEndOfStatement();
4794 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4795 if (!SaveOpnd.isGPRAsmReg()) {
4796 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4797 Parser.eatToEndOfStatement();
4800 Save = SaveOpnd.getGPR32Reg();
4803 if (!eatComma("unexpected token, expected comma"))
4807 if (Parser.parseExpression(Expr)) {
4808 reportParseError("expected expression");
4812 if (Expr->getKind() != MCExpr::SymbolRef) {
4813 reportParseError("expected symbol");
4816 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4818 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4823 bool MipsAsmParser::parseDirectiveNaN() {
4824 MCAsmParser &Parser = getParser();
4825 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4826 const AsmToken &Tok = Parser.getTok();
4828 if (Tok.getString() == "2008") {
4830 getTargetStreamer().emitDirectiveNaN2008();
4832 } else if (Tok.getString() == "legacy") {
4834 getTargetStreamer().emitDirectiveNaNLegacy();
4838 // If we don't recognize the option passed to the .nan
4839 // directive (e.g. no option or unknown option), emit an error.
4840 reportParseError("invalid option in .nan directive");
4844 bool MipsAsmParser::parseDirectiveSet() {
4845 MCAsmParser &Parser = getParser();
4846 // Get the next token.
4847 const AsmToken &Tok = Parser.getTok();
4849 if (Tok.getString() == "noat") {
4850 return parseSetNoAtDirective();
4851 } else if (Tok.getString() == "at") {
4852 return parseSetAtDirective();
4853 } else if (Tok.getString() == "arch") {
4854 return parseSetArchDirective();
4855 } else if (Tok.getString() == "fp") {
4856 return parseSetFpDirective();
4857 } else if (Tok.getString() == "oddspreg") {
4858 return parseSetOddSPRegDirective();
4859 } else if (Tok.getString() == "nooddspreg") {
4860 return parseSetNoOddSPRegDirective();
4861 } else if (Tok.getString() == "pop") {
4862 return parseSetPopDirective();
4863 } else if (Tok.getString() == "push") {
4864 return parseSetPushDirective();
4865 } else if (Tok.getString() == "reorder") {
4866 return parseSetReorderDirective();
4867 } else if (Tok.getString() == "noreorder") {
4868 return parseSetNoReorderDirective();
4869 } else if (Tok.getString() == "macro") {
4870 return parseSetMacroDirective();
4871 } else if (Tok.getString() == "nomacro") {
4872 return parseSetNoMacroDirective();
4873 } else if (Tok.getString() == "mips16") {
4874 return parseSetMips16Directive();
4875 } else if (Tok.getString() == "nomips16") {
4876 return parseSetNoMips16Directive();
4877 } else if (Tok.getString() == "nomicromips") {
4878 getTargetStreamer().emitDirectiveSetNoMicroMips();
4879 Parser.eatToEndOfStatement();
4881 } else if (Tok.getString() == "micromips") {
4882 return parseSetFeature(Mips::FeatureMicroMips);
4883 } else if (Tok.getString() == "mips0") {
4884 return parseSetMips0Directive();
4885 } else if (Tok.getString() == "mips1") {
4886 return parseSetFeature(Mips::FeatureMips1);
4887 } else if (Tok.getString() == "mips2") {
4888 return parseSetFeature(Mips::FeatureMips2);
4889 } else if (Tok.getString() == "mips3") {
4890 return parseSetFeature(Mips::FeatureMips3);
4891 } else if (Tok.getString() == "mips4") {
4892 return parseSetFeature(Mips::FeatureMips4);
4893 } else if (Tok.getString() == "mips5") {
4894 return parseSetFeature(Mips::FeatureMips5);
4895 } else if (Tok.getString() == "mips32") {
4896 return parseSetFeature(Mips::FeatureMips32);
4897 } else if (Tok.getString() == "mips32r2") {
4898 return parseSetFeature(Mips::FeatureMips32r2);
4899 } else if (Tok.getString() == "mips32r3") {
4900 return parseSetFeature(Mips::FeatureMips32r3);
4901 } else if (Tok.getString() == "mips32r5") {
4902 return parseSetFeature(Mips::FeatureMips32r5);
4903 } else if (Tok.getString() == "mips32r6") {
4904 return parseSetFeature(Mips::FeatureMips32r6);
4905 } else if (Tok.getString() == "mips64") {
4906 return parseSetFeature(Mips::FeatureMips64);
4907 } else if (Tok.getString() == "mips64r2") {
4908 return parseSetFeature(Mips::FeatureMips64r2);
4909 } else if (Tok.getString() == "mips64r3") {
4910 return parseSetFeature(Mips::FeatureMips64r3);
4911 } else if (Tok.getString() == "mips64r5") {
4912 return parseSetFeature(Mips::FeatureMips64r5);
4913 } else if (Tok.getString() == "mips64r6") {
4914 return parseSetFeature(Mips::FeatureMips64r6);
4915 } else if (Tok.getString() == "dsp") {
4916 return parseSetFeature(Mips::FeatureDSP);
4917 } else if (Tok.getString() == "nodsp") {
4918 return parseSetNoDspDirective();
4919 } else if (Tok.getString() == "msa") {
4920 return parseSetMsaDirective();
4921 } else if (Tok.getString() == "nomsa") {
4922 return parseSetNoMsaDirective();
4923 } else if (Tok.getString() == "softfloat") {
4924 return parseSetSoftFloatDirective();
4925 } else if (Tok.getString() == "hardfloat") {
4926 return parseSetHardFloatDirective();
4928 // It is just an identifier, look for an assignment.
4929 parseSetAssignment();
4936 /// parseDataDirective
4937 /// ::= .word [ expression (, expression)* ]
4938 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4939 MCAsmParser &Parser = getParser();
4940 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4942 const MCExpr *Value;
4943 if (getParser().parseExpression(Value))
4946 getParser().getStreamer().EmitValue(Value, Size);
4948 if (getLexer().is(AsmToken::EndOfStatement))
4951 if (getLexer().isNot(AsmToken::Comma))
4952 return Error(L, "unexpected token, expected comma");
4961 /// parseDirectiveGpWord
4962 /// ::= .gpword local_sym
4963 bool MipsAsmParser::parseDirectiveGpWord() {
4964 MCAsmParser &Parser = getParser();
4965 const MCExpr *Value;
4966 // EmitGPRel32Value requires an expression, so we are using base class
4967 // method to evaluate the expression.
4968 if (getParser().parseExpression(Value))
4970 getParser().getStreamer().EmitGPRel32Value(Value);
4972 if (getLexer().isNot(AsmToken::EndOfStatement))
4973 return Error(getLexer().getLoc(),
4974 "unexpected token, expected end of statement");
4975 Parser.Lex(); // Eat EndOfStatement token.
4979 /// parseDirectiveGpDWord
4980 /// ::= .gpdword local_sym
4981 bool MipsAsmParser::parseDirectiveGpDWord() {
4982 MCAsmParser &Parser = getParser();
4983 const MCExpr *Value;
4984 // EmitGPRel64Value requires an expression, so we are using base class
4985 // method to evaluate the expression.
4986 if (getParser().parseExpression(Value))
4988 getParser().getStreamer().EmitGPRel64Value(Value);
4990 if (getLexer().isNot(AsmToken::EndOfStatement))
4991 return Error(getLexer().getLoc(),
4992 "unexpected token, expected end of statement");
4993 Parser.Lex(); // Eat EndOfStatement token.
4997 bool MipsAsmParser::parseDirectiveOption() {
4998 MCAsmParser &Parser = getParser();
4999 // Get the option token.
5000 AsmToken Tok = Parser.getTok();
5001 // At the moment only identifiers are supported.
5002 if (Tok.isNot(AsmToken::Identifier)) {
5003 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5004 Parser.eatToEndOfStatement();
5008 StringRef Option = Tok.getIdentifier();
5010 if (Option == "pic0") {
5011 // MipsAsmParser needs to know if the current PIC mode changes.
5012 IsPicEnabled = false;
5014 getTargetStreamer().emitDirectiveOptionPic0();
5016 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5017 Error(Parser.getTok().getLoc(),
5018 "unexpected token, expected end of statement");
5019 Parser.eatToEndOfStatement();
5024 if (Option == "pic2") {
5025 // MipsAsmParser needs to know if the current PIC mode changes.
5026 IsPicEnabled = true;
5028 getTargetStreamer().emitDirectiveOptionPic2();
5030 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5031 Error(Parser.getTok().getLoc(),
5032 "unexpected token, expected end of statement");
5033 Parser.eatToEndOfStatement();
5039 Warning(Parser.getTok().getLoc(),
5040 "unknown option, expected 'pic0' or 'pic2'");
5041 Parser.eatToEndOfStatement();
5045 /// parseInsnDirective
5047 bool MipsAsmParser::parseInsnDirective() {
5048 // If this is not the end of the statement, report an error.
5049 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5050 reportParseError("unexpected token, expected end of statement");
5054 // The actual label marking happens in
5055 // MipsELFStreamer::createPendingLabelRelocs().
5056 getTargetStreamer().emitDirectiveInsn();
5058 getParser().Lex(); // Eat EndOfStatement token.
5062 /// parseDirectiveModule
5063 /// ::= .module oddspreg
5064 /// ::= .module nooddspreg
5065 /// ::= .module fp=value
5066 /// ::= .module softfloat
5067 /// ::= .module hardfloat
5068 bool MipsAsmParser::parseDirectiveModule() {
5069 MCAsmParser &Parser = getParser();
5070 MCAsmLexer &Lexer = getLexer();
5071 SMLoc L = Lexer.getLoc();
5073 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5074 // TODO : get a better message.
5075 reportParseError(".module directive must appear before any code");
5080 if (Parser.parseIdentifier(Option)) {
5081 reportParseError("expected .module option identifier");
5085 if (Option == "oddspreg") {
5086 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5088 // Synchronize the abiflags information with the FeatureBits information we
5090 getTargetStreamer().updateABIInfo(*this);
5092 // If printing assembly, use the recently updated abiflags information.
5093 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5094 // emitted at the end).
5095 getTargetStreamer().emitDirectiveModuleOddSPReg();
5097 // If this is not the end of the statement, report an error.
5098 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5099 reportParseError("unexpected token, expected end of statement");
5103 return false; // parseDirectiveModule has finished successfully.
5104 } else if (Option == "nooddspreg") {
5106 Error(L, "'.module nooddspreg' requires the O32 ABI");
5110 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5112 // Synchronize the abiflags information with the FeatureBits information we
5114 getTargetStreamer().updateABIInfo(*this);
5116 // If printing assembly, use the recently updated abiflags information.
5117 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5118 // emitted at the end).
5119 getTargetStreamer().emitDirectiveModuleOddSPReg();
5121 // If this is not the end of the statement, report an error.
5122 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5123 reportParseError("unexpected token, expected end of statement");
5127 return false; // parseDirectiveModule has finished successfully.
5128 } else if (Option == "fp") {
5129 return parseDirectiveModuleFP();
5130 } else if (Option == "softfloat") {
5131 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5133 // Synchronize the ABI Flags information with the FeatureBits information we
5135 getTargetStreamer().updateABIInfo(*this);
5137 // If printing assembly, use the recently updated ABI Flags information.
5138 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5140 getTargetStreamer().emitDirectiveModuleSoftFloat();
5142 // If this is not the end of the statement, report an error.
5143 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5144 reportParseError("unexpected token, expected end of statement");
5148 return false; // parseDirectiveModule has finished successfully.
5149 } else if (Option == "hardfloat") {
5150 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5152 // Synchronize the ABI Flags information with the FeatureBits information we
5154 getTargetStreamer().updateABIInfo(*this);
5156 // If printing assembly, use the recently updated ABI Flags information.
5157 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5159 getTargetStreamer().emitDirectiveModuleHardFloat();
5161 // If this is not the end of the statement, report an error.
5162 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5163 reportParseError("unexpected token, expected end of statement");
5167 return false; // parseDirectiveModule has finished successfully.
5169 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5173 /// parseDirectiveModuleFP
5177 bool MipsAsmParser::parseDirectiveModuleFP() {
5178 MCAsmParser &Parser = getParser();
5179 MCAsmLexer &Lexer = getLexer();
5181 if (Lexer.isNot(AsmToken::Equal)) {
5182 reportParseError("unexpected token, expected equals sign '='");
5185 Parser.Lex(); // Eat '=' token.
5187 MipsABIFlagsSection::FpABIKind FpABI;
5188 if (!parseFpABIValue(FpABI, ".module"))
5191 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5192 reportParseError("unexpected token, expected end of statement");
5196 // Synchronize the abiflags information with the FeatureBits information we
5198 getTargetStreamer().updateABIInfo(*this);
5200 // If printing assembly, use the recently updated abiflags information.
5201 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5202 // emitted at the end).
5203 getTargetStreamer().emitDirectiveModuleFP();
5205 Parser.Lex(); // Consume the EndOfStatement.
5209 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5210 StringRef Directive) {
5211 MCAsmParser &Parser = getParser();
5212 MCAsmLexer &Lexer = getLexer();
5213 bool ModuleLevelOptions = Directive == ".module";
5215 if (Lexer.is(AsmToken::Identifier)) {
5216 StringRef Value = Parser.getTok().getString();
5219 if (Value != "xx") {
5220 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5225 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5229 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5230 if (ModuleLevelOptions) {
5231 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5232 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5234 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5235 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5240 if (Lexer.is(AsmToken::Integer)) {
5241 unsigned Value = Parser.getTok().getIntVal();
5244 if (Value != 32 && Value != 64) {
5245 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5251 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5255 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5256 if (ModuleLevelOptions) {
5257 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5258 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5260 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5261 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5264 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5265 if (ModuleLevelOptions) {
5266 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5267 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5269 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5270 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5280 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5281 MCAsmParser &Parser = getParser();
5282 StringRef IDVal = DirectiveID.getString();
5284 if (IDVal == ".cpload")
5285 return parseDirectiveCpLoad(DirectiveID.getLoc());
5286 if (IDVal == ".dword") {
5287 parseDataDirective(8, DirectiveID.getLoc());
5290 if (IDVal == ".ent") {
5291 StringRef SymbolName;
5293 if (Parser.parseIdentifier(SymbolName)) {
5294 reportParseError("expected identifier after .ent");
5298 // There's an undocumented extension that allows an integer to
5299 // follow the name of the procedure which AFAICS is ignored by GAS.
5300 // Example: .ent foo,2
5301 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5302 if (getLexer().isNot(AsmToken::Comma)) {
5303 // Even though we accept this undocumented extension for compatibility
5304 // reasons, the additional integer argument does not actually change
5305 // the behaviour of the '.ent' directive, so we would like to discourage
5306 // its use. We do this by not referring to the extended version in
5307 // error messages which are not directly related to its use.
5308 reportParseError("unexpected token, expected end of statement");
5311 Parser.Lex(); // Eat the comma.
5312 const MCExpr *DummyNumber;
5313 int64_t DummyNumberVal;
5314 // If the user was explicitly trying to use the extended version,
5315 // we still give helpful extension-related error messages.
5316 if (Parser.parseExpression(DummyNumber)) {
5317 reportParseError("expected number after comma");
5320 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5321 reportParseError("expected an absolute expression after comma");
5326 // If this is not the end of the statement, report an error.
5327 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5328 reportParseError("unexpected token, expected end of statement");
5332 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5334 getTargetStreamer().emitDirectiveEnt(*Sym);
5339 if (IDVal == ".end") {
5340 StringRef SymbolName;
5342 if (Parser.parseIdentifier(SymbolName)) {
5343 reportParseError("expected identifier after .end");
5347 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5348 reportParseError("unexpected token, expected end of statement");
5352 if (CurrentFn == nullptr) {
5353 reportParseError(".end used without .ent");
5357 if ((SymbolName != CurrentFn->getName())) {
5358 reportParseError(".end symbol does not match .ent symbol");
5362 getTargetStreamer().emitDirectiveEnd(SymbolName);
5363 CurrentFn = nullptr;
5367 if (IDVal == ".frame") {
5368 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5369 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5370 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5371 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5372 reportParseError("expected stack register");
5376 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5377 if (!StackRegOpnd.isGPRAsmReg()) {
5378 reportParseError(StackRegOpnd.getStartLoc(),
5379 "expected general purpose register");
5382 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5384 if (Parser.getTok().is(AsmToken::Comma))
5387 reportParseError("unexpected token, expected comma");
5391 // Parse the frame size.
5392 const MCExpr *FrameSize;
5393 int64_t FrameSizeVal;
5395 if (Parser.parseExpression(FrameSize)) {
5396 reportParseError("expected frame size value");
5400 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5401 reportParseError("frame size not an absolute expression");
5405 if (Parser.getTok().is(AsmToken::Comma))
5408 reportParseError("unexpected token, expected comma");
5412 // Parse the return register.
5414 ResTy = parseAnyRegister(TmpReg);
5415 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5416 reportParseError("expected return register");
5420 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5421 if (!ReturnRegOpnd.isGPRAsmReg()) {
5422 reportParseError(ReturnRegOpnd.getStartLoc(),
5423 "expected general purpose register");
5427 // If this is not the end of the statement, report an error.
5428 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5429 reportParseError("unexpected token, expected end of statement");
5433 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5434 ReturnRegOpnd.getGPR32Reg());
5438 if (IDVal == ".set") {
5439 return parseDirectiveSet();
5442 if (IDVal == ".mask" || IDVal == ".fmask") {
5443 // .mask bitmask, frame_offset
5444 // bitmask: One bit for each register used.
5445 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5446 // first register is expected to be saved.
5448 // .mask 0x80000000, -4
5449 // .fmask 0x80000000, -4
5452 // Parse the bitmask
5453 const MCExpr *BitMask;
5456 if (Parser.parseExpression(BitMask)) {
5457 reportParseError("expected bitmask value");
5461 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5462 reportParseError("bitmask not an absolute expression");
5466 if (Parser.getTok().is(AsmToken::Comma))
5469 reportParseError("unexpected token, expected comma");
5473 // Parse the frame_offset
5474 const MCExpr *FrameOffset;
5475 int64_t FrameOffsetVal;
5477 if (Parser.parseExpression(FrameOffset)) {
5478 reportParseError("expected frame offset value");
5482 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5483 reportParseError("frame offset not an absolute expression");
5487 // If this is not the end of the statement, report an error.
5488 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5489 reportParseError("unexpected token, expected end of statement");
5493 if (IDVal == ".mask")
5494 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5496 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5500 if (IDVal == ".nan")
5501 return parseDirectiveNaN();
5503 if (IDVal == ".gpword") {
5504 parseDirectiveGpWord();
5508 if (IDVal == ".gpdword") {
5509 parseDirectiveGpDWord();
5513 if (IDVal == ".word") {
5514 parseDataDirective(4, DirectiveID.getLoc());
5518 if (IDVal == ".option")
5519 return parseDirectiveOption();
5521 if (IDVal == ".abicalls") {
5522 getTargetStreamer().emitDirectiveAbiCalls();
5523 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5524 Error(Parser.getTok().getLoc(),
5525 "unexpected token, expected end of statement");
5527 Parser.eatToEndOfStatement();
5532 if (IDVal == ".cpsetup")
5533 return parseDirectiveCPSetup();
5535 if (IDVal == ".module")
5536 return parseDirectiveModule();
5538 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5539 return parseInternalDirectiveReallowModule();
5541 if (IDVal == ".insn")
5542 return parseInsnDirective();
5547 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5548 // If this is not the end of the statement, report an error.
5549 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5550 reportParseError("unexpected token, expected end of statement");
5554 getTargetStreamer().reallowModuleDirective();
5556 getParser().Lex(); // Eat EndOfStatement token.
5560 extern "C" void LLVMInitializeMipsAsmParser() {
5561 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5562 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5563 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5564 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5567 #define GET_REGISTER_MATCHER
5568 #define GET_MATCHER_IMPLEMENTATION
5569 #include "MipsGenAsmMatcher.inc"