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'
122 // Print a warning along with its fix-it message at the given range.
123 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
124 SMRange Range, bool ShowColors = true);
126 #define GET_ASSEMBLER_HEADER
127 #include "MipsGenAsmMatcher.inc"
129 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
131 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
132 OperandVector &Operands, MCStreamer &Out,
134 bool MatchingInlineAsm) override;
136 /// Parse a register as used in CFI directives
137 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
139 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
141 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
143 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
144 SMLoc NameLoc, OperandVector &Operands) override;
146 bool ParseDirective(AsmToken DirectiveID) override;
148 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
150 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
151 StringRef Identifier, SMLoc S);
152 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
154 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
155 OperandMatchResultTy parseImm(OperandVector &Operands);
156 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
157 OperandMatchResultTy parseInvNum(OperandVector &Operands);
158 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
159 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
160 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
161 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
163 bool searchSymbolAlias(OperandVector &Operands);
165 bool parseOperand(OperandVector &, StringRef Mnemonic);
167 bool needsExpansion(MCInst &Inst);
169 // Expands assembly pseudo instructions.
170 // Returns false on success, true otherwise.
171 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
172 SmallVectorImpl<MCInst> &Instructions);
174 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
175 SmallVectorImpl<MCInst> &Instructions);
177 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
178 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
179 SmallVectorImpl<MCInst> &Instructions);
181 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
182 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
189 const MCOperand &Offset, bool Is32BitAddress,
190 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
192 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
195 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
199 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
200 SmallVectorImpl<MCInst> &Instructions);
202 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions);
205 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions);
208 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
212 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
213 SmallVectorImpl<MCInst> &Instructions);
215 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
216 SmallVectorImpl<MCInst> &Instructions);
218 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions);
221 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
222 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
224 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
225 SmallVectorImpl<MCInst> &Instructions);
227 bool reportParseError(Twine ErrorMsg);
228 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
230 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
231 bool parseRelocOperand(const MCExpr *&Res);
233 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
235 bool isEvaluated(const MCExpr *Expr);
236 bool parseSetMips0Directive();
237 bool parseSetArchDirective();
238 bool parseSetFeature(uint64_t Feature);
239 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
240 bool parseDirectiveCpLoad(SMLoc Loc);
241 bool parseDirectiveCpRestore(SMLoc Loc);
242 bool parseDirectiveCPSetup();
243 bool parseDirectiveNaN();
244 bool parseDirectiveSet();
245 bool parseDirectiveOption();
246 bool parseInsnDirective();
248 bool parseSetAtDirective();
249 bool parseSetNoAtDirective();
250 bool parseSetMacroDirective();
251 bool parseSetNoMacroDirective();
252 bool parseSetMsaDirective();
253 bool parseSetNoMsaDirective();
254 bool parseSetNoDspDirective();
255 bool parseSetReorderDirective();
256 bool parseSetNoReorderDirective();
257 bool parseSetMips16Directive();
258 bool parseSetNoMips16Directive();
259 bool parseSetFpDirective();
260 bool parseSetOddSPRegDirective();
261 bool parseSetNoOddSPRegDirective();
262 bool parseSetPopDirective();
263 bool parseSetPushDirective();
264 bool parseSetSoftFloatDirective();
265 bool parseSetHardFloatDirective();
267 bool parseSetAssignment();
269 bool parseDataDirective(unsigned Size, SMLoc L);
270 bool parseDirectiveGpWord();
271 bool parseDirectiveGpDWord();
272 bool parseDirectiveModule();
273 bool parseDirectiveModuleFP();
274 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
275 StringRef Directive);
277 bool parseInternalDirectiveReallowModule();
279 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
281 bool eatComma(StringRef ErrorStr);
283 int matchCPURegisterName(StringRef Symbol);
285 int matchHWRegsRegisterName(StringRef Symbol);
287 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
289 int matchFPURegisterName(StringRef Name);
291 int matchFCCRegisterName(StringRef Name);
293 int matchACRegisterName(StringRef Name);
295 int matchMSA128RegisterName(StringRef Name);
297 int matchMSA128CtrlRegisterName(StringRef Name);
299 unsigned getReg(int RC, int RegNo);
301 unsigned getGPR(int RegNo);
303 /// Returns the internal register number for the current AT. Also checks if
304 /// the current AT is unavailable (set to $0) and gives an error if it is.
305 /// This should be used in pseudo-instruction expansions which need AT.
306 unsigned getATReg(SMLoc Loc);
308 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
309 SmallVectorImpl<MCInst> &Instructions);
311 // Helper function that checks if the value of a vector index is within the
312 // boundaries of accepted values for each RegisterKind
313 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
314 bool validateMSAIndex(int Val, int RegKind);
316 // Selects a new architecture by updating the FeatureBits with the necessary
317 // info including implied dependencies.
318 // Internally, it clears all the feature bits related to *any* architecture
319 // and selects the new one using the ToggleFeature functionality of the
320 // MCSubtargetInfo object that handles implied dependencies. The reason we
321 // clear all the arch related bits manually is because ToggleFeature only
322 // clears the features that imply the feature being cleared and not the
323 // features implied by the feature being cleared. This is easier to see
325 // --------------------------------------------------
326 // | Feature | Implies |
327 // | -------------------------------------------------|
328 // | FeatureMips1 | None |
329 // | FeatureMips2 | FeatureMips1 |
330 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
331 // | FeatureMips4 | FeatureMips3 |
333 // --------------------------------------------------
335 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
336 // FeatureMipsGP64 | FeatureMips1)
337 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
338 void selectArch(StringRef ArchFeature) {
339 FeatureBitset FeatureBits = STI.getFeatureBits();
340 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
341 STI.setFeatureBits(FeatureBits);
342 setAvailableFeatures(
343 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
344 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
347 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
348 if (!(STI.getFeatureBits()[Feature])) {
349 setAvailableFeatures(
350 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
351 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
355 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
356 if (STI.getFeatureBits()[Feature]) {
357 setAvailableFeatures(
358 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
359 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
363 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
364 setFeatureBits(Feature, FeatureString);
365 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
368 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
369 clearFeatureBits(Feature, FeatureString);
370 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
374 enum MipsMatchResultTy {
375 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
376 #define GET_OPERAND_DIAGNOSTIC_TYPES
377 #include "MipsGenAsmMatcher.inc"
378 #undef GET_OPERAND_DIAGNOSTIC_TYPES
382 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
383 const MCInstrInfo &MII, const MCTargetOptions &Options)
384 : MCTargetAsmParser(Options), STI(sti),
385 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
386 sti.getCPU(), Options)) {
387 MCAsmParserExtension::Initialize(parser);
389 parser.addAliasForDirective(".asciiz", ".asciz");
391 // Initialize the set of available features.
392 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
394 // Remember the initial assembler options. The user can not modify these.
395 AssemblerOptions.push_back(
396 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
398 // Create an assembler options environment for the user to modify.
399 AssemblerOptions.push_back(
400 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
402 getTargetStreamer().updateABIInfo(*this);
404 if (!isABI_O32() && !useOddSPReg() != 0)
405 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
410 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
412 IsCpRestoreSet = false;
413 CpRestoreOffset = -1;
415 Triple TheTriple(sti.getTargetTriple());
416 if ((TheTriple.getArch() == Triple::mips) ||
417 (TheTriple.getArch() == Triple::mips64))
418 IsLittleEndian = false;
420 IsLittleEndian = true;
423 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
424 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
426 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
427 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
428 const MipsABIInfo &getABI() const { return ABI; }
429 bool isABI_N32() const { return ABI.IsN32(); }
430 bool isABI_N64() const { return ABI.IsN64(); }
431 bool isABI_O32() const { return ABI.IsO32(); }
432 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
434 bool useOddSPReg() const {
435 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
438 bool inMicroMipsMode() const {
439 return STI.getFeatureBits()[Mips::FeatureMicroMips];
441 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
442 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
443 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
444 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
445 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
446 bool hasMips32() const {
447 return STI.getFeatureBits()[Mips::FeatureMips32];
449 bool hasMips64() const {
450 return STI.getFeatureBits()[Mips::FeatureMips64];
452 bool hasMips32r2() const {
453 return STI.getFeatureBits()[Mips::FeatureMips32r2];
455 bool hasMips64r2() const {
456 return STI.getFeatureBits()[Mips::FeatureMips64r2];
458 bool hasMips32r3() const {
459 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
461 bool hasMips64r3() const {
462 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
464 bool hasMips32r5() const {
465 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
467 bool hasMips64r5() const {
468 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
470 bool hasMips32r6() const {
471 return STI.getFeatureBits()[Mips::FeatureMips32r6];
473 bool hasMips64r6() const {
474 return STI.getFeatureBits()[Mips::FeatureMips64r6];
477 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
478 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
479 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
480 bool hasCnMips() const {
481 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
488 bool inMips16Mode() const {
489 return STI.getFeatureBits()[Mips::FeatureMips16];
492 bool useTraps() const {
493 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
496 bool useSoftFloat() const {
497 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
500 /// Warn if RegIndex is the same as the current AT.
501 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
503 void warnIfNoMacro(SMLoc Loc);
505 bool isLittle() const { return IsLittleEndian; }
511 /// MipsOperand - Instances of this class represent a parsed Mips machine
513 class MipsOperand : public MCParsedAsmOperand {
515 /// Broad categories of register classes
516 /// The exact class is finalized by the render method.
518 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
519 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
521 RegKind_FCC = 4, /// FCC
522 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
523 RegKind_MSACtrl = 16, /// MSA control registers
524 RegKind_COP2 = 32, /// COP2
525 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
527 RegKind_CCR = 128, /// CCR
528 RegKind_HWRegs = 256, /// HWRegs
529 RegKind_COP3 = 512, /// COP3
530 RegKind_COP0 = 1024, /// COP0
531 /// Potentially any (e.g. $1)
532 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
533 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
534 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
539 k_Immediate, /// An immediate (possibly involving symbol references)
540 k_Memory, /// Base + Offset Memory Address
541 k_PhysRegister, /// A physical register from the Mips namespace
542 k_RegisterIndex, /// A register index in one or more RegKind.
543 k_Token, /// A simple token
544 k_RegList, /// A physical register list
545 k_RegPair /// A pair of physical register
549 MipsOperand(KindTy K, MipsAsmParser &Parser)
550 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
553 /// For diagnostics, and checking the assembler temporary
554 MipsAsmParser &AsmParser;
562 unsigned Num; /// Register Number
566 unsigned Index; /// Index into the register class
567 RegKind Kind; /// Bitfield of the kinds it could possibly be
568 const MCRegisterInfo *RegInfo;
581 SmallVector<unsigned, 10> *List;
586 struct PhysRegOp PhysReg;
587 struct RegIdxOp RegIdx;
590 struct RegListOp RegList;
593 SMLoc StartLoc, EndLoc;
595 /// Internal constructor for register kinds
596 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
597 const MCRegisterInfo *RegInfo,
599 MipsAsmParser &Parser) {
600 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
601 Op->RegIdx.Index = Index;
602 Op->RegIdx.RegInfo = RegInfo;
603 Op->RegIdx.Kind = RegKind;
610 /// Coerce the register to GPR32 and return the real register for the current
612 unsigned getGPR32Reg() const {
613 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
614 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
615 unsigned ClassID = Mips::GPR32RegClassID;
616 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
619 /// Coerce the register to GPR32 and return the real register for the current
621 unsigned getGPRMM16Reg() const {
622 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
623 unsigned ClassID = Mips::GPR32RegClassID;
624 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
627 /// Coerce the register to GPR64 and return the real register for the current
629 unsigned getGPR64Reg() const {
630 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
631 unsigned ClassID = Mips::GPR64RegClassID;
632 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
636 /// Coerce the register to AFGR64 and return the real register for the current
638 unsigned getAFGR64Reg() const {
639 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
640 if (RegIdx.Index % 2 != 0)
641 AsmParser.Warning(StartLoc, "Float register should be even.");
642 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
643 .getRegister(RegIdx.Index / 2);
646 /// Coerce the register to FGR64 and return the real register for the current
648 unsigned getFGR64Reg() const {
649 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
650 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
651 .getRegister(RegIdx.Index);
654 /// Coerce the register to FGR32 and return the real register for the current
656 unsigned getFGR32Reg() const {
657 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
658 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
659 .getRegister(RegIdx.Index);
662 /// Coerce the register to FGRH32 and return the real register for the current
664 unsigned getFGRH32Reg() const {
665 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
666 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
667 .getRegister(RegIdx.Index);
670 /// Coerce the register to FCC and return the real register for the current
672 unsigned getFCCReg() const {
673 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
674 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
675 .getRegister(RegIdx.Index);
678 /// Coerce the register to MSA128 and return the real register for the current
680 unsigned getMSA128Reg() const {
681 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
682 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
684 unsigned ClassID = Mips::MSA128BRegClassID;
685 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
688 /// Coerce the register to MSACtrl and return the real register for the
690 unsigned getMSACtrlReg() const {
691 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
692 unsigned ClassID = Mips::MSACtrlRegClassID;
693 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
696 /// Coerce the register to COP0 and return the real register for the
698 unsigned getCOP0Reg() const {
699 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
700 unsigned ClassID = Mips::COP0RegClassID;
701 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
704 /// Coerce the register to COP2 and return the real register for the
706 unsigned getCOP2Reg() const {
707 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
708 unsigned ClassID = Mips::COP2RegClassID;
709 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
712 /// Coerce the register to COP3 and return the real register for the
714 unsigned getCOP3Reg() const {
715 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
716 unsigned ClassID = Mips::COP3RegClassID;
717 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
720 /// Coerce the register to ACC64DSP and return the real register for the
722 unsigned getACC64DSPReg() const {
723 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
724 unsigned ClassID = Mips::ACC64DSPRegClassID;
725 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
728 /// Coerce the register to HI32DSP and return the real register for the
730 unsigned getHI32DSPReg() const {
731 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
732 unsigned ClassID = Mips::HI32DSPRegClassID;
733 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
736 /// Coerce the register to LO32DSP and return the real register for the
738 unsigned getLO32DSPReg() const {
739 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
740 unsigned ClassID = Mips::LO32DSPRegClassID;
741 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
744 /// Coerce the register to CCR and return the real register for the
746 unsigned getCCRReg() const {
747 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
748 unsigned ClassID = Mips::CCRRegClassID;
749 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
752 /// Coerce the register to HWRegs and return the real register for the
754 unsigned getHWRegsReg() const {
755 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
756 unsigned ClassID = Mips::HWRegsRegClassID;
757 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
761 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
762 // Add as immediate when possible. Null MCExpr = 0.
764 Inst.addOperand(MCOperand::createImm(0));
765 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
766 Inst.addOperand(MCOperand::createImm(CE->getValue()));
768 Inst.addOperand(MCOperand::createExpr(Expr));
771 void addRegOperands(MCInst &Inst, unsigned N) const {
772 llvm_unreachable("Use a custom parser instead");
775 /// Render the operand to an MCInst as a GPR32
776 /// Asserts if the wrong number of operands are requested, or the operand
777 /// is not a k_RegisterIndex compatible with RegKind_GPR
778 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
783 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
788 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
789 assert(N == 1 && "Invalid number of operands!");
790 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
793 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
794 assert(N == 1 && "Invalid number of operands!");
795 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
798 /// Render the operand to an MCInst as a GPR64
799 /// Asserts if the wrong number of operands are requested, or the operand
800 /// is not a k_RegisterIndex compatible with RegKind_GPR
801 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
802 assert(N == 1 && "Invalid number of operands!");
803 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
806 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
807 assert(N == 1 && "Invalid number of operands!");
808 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
811 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
812 assert(N == 1 && "Invalid number of operands!");
813 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
816 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
817 assert(N == 1 && "Invalid number of operands!");
818 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
819 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
820 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
821 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
825 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
826 assert(N == 1 && "Invalid number of operands!");
827 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
830 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
831 assert(N == 1 && "Invalid number of operands!");
832 Inst.addOperand(MCOperand::createReg(getFCCReg()));
835 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
836 assert(N == 1 && "Invalid number of operands!");
837 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
840 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 1 && "Invalid number of operands!");
842 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
845 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
846 assert(N == 1 && "Invalid number of operands!");
847 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
850 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
851 assert(N == 1 && "Invalid number of operands!");
852 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
855 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
856 assert(N == 1 && "Invalid number of operands!");
857 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
860 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
861 assert(N == 1 && "Invalid number of operands!");
862 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
865 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
866 assert(N == 1 && "Invalid number of operands!");
867 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
870 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
871 assert(N == 1 && "Invalid number of operands!");
872 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
875 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
876 assert(N == 1 && "Invalid number of operands!");
877 Inst.addOperand(MCOperand::createReg(getCCRReg()));
880 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
881 assert(N == 1 && "Invalid number of operands!");
882 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
885 void addImmOperands(MCInst &Inst, unsigned N) const {
886 assert(N == 1 && "Invalid number of operands!");
887 const MCExpr *Expr = getImm();
891 void addMemOperands(MCInst &Inst, unsigned N) const {
892 assert(N == 2 && "Invalid number of operands!");
894 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
895 ? getMemBase()->getGPR64Reg()
896 : getMemBase()->getGPR32Reg()));
898 const MCExpr *Expr = getMemOff();
902 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
903 assert(N == 2 && "Invalid number of operands!");
905 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
907 const MCExpr *Expr = getMemOff();
911 void addRegListOperands(MCInst &Inst, unsigned N) const {
912 assert(N == 1 && "Invalid number of operands!");
914 for (auto RegNo : getRegList())
915 Inst.addOperand(MCOperand::createReg(RegNo));
918 void addRegPairOperands(MCInst &Inst, unsigned N) const {
919 assert(N == 2 && "Invalid number of operands!");
920 unsigned RegNo = getRegPair();
921 Inst.addOperand(MCOperand::createReg(RegNo++));
922 Inst.addOperand(MCOperand::createReg(RegNo));
925 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
926 assert(N == 2 && "Invalid number of operands!");
927 for (auto RegNo : getRegList())
928 Inst.addOperand(MCOperand::createReg(RegNo));
931 bool isReg() const override {
932 // As a special case until we sort out the definition of div/divu, pretend
933 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
934 if (isGPRAsmReg() && RegIdx.Index == 0)
937 return Kind == k_PhysRegister;
939 bool isRegIdx() const { return Kind == k_RegisterIndex; }
940 bool isImm() const override { return Kind == k_Immediate; }
941 bool isConstantImm() const {
942 return isImm() && dyn_cast<MCConstantExpr>(getImm());
944 template <unsigned Bits> bool isUImm() const {
945 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
947 bool isToken() const override {
948 // Note: It's not possible to pretend that other operand kinds are tokens.
949 // The matcher emitter checks tokens first.
950 return Kind == k_Token;
952 bool isMem() const override { return Kind == k_Memory; }
953 bool isConstantMemOff() const {
954 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
956 template <unsigned Bits> bool isMemWithSimmOffset() const {
957 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
958 && getMemBase()->isGPRAsmReg();
960 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
961 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
962 getMemBase()->isGPRAsmReg();
964 bool isMemWithGRPMM16Base() const {
965 return isMem() && getMemBase()->isMM16AsmReg();
967 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
968 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
969 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
971 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
972 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
973 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
974 && (getMemBase()->getGPR32Reg() == Mips::SP);
976 bool isRegList16() const {
980 int Size = RegList.List->size();
981 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
982 RegList.List->back() != Mips::RA)
985 int PrevReg = *RegList.List->begin();
986 for (int i = 1; i < Size - 1; i++) {
987 int Reg = (*(RegList.List))[i];
988 if ( Reg != PrevReg + 1)
995 bool isInvNum() const { return Kind == k_Immediate; }
996 bool isLSAImm() const {
997 if (!isConstantImm())
999 int64_t Val = getConstantImm();
1000 return 1 <= Val && Val <= 4;
1002 bool isRegList() const { return Kind == k_RegList; }
1003 bool isMovePRegPair() const {
1004 if (Kind != k_RegList || RegList.List->size() != 2)
1007 unsigned R0 = RegList.List->front();
1008 unsigned R1 = RegList.List->back();
1010 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1011 (R0 == Mips::A1 && R1 == Mips::A3) ||
1012 (R0 == Mips::A2 && R1 == Mips::A3) ||
1013 (R0 == Mips::A0 && R1 == Mips::S5) ||
1014 (R0 == Mips::A0 && R1 == Mips::S6) ||
1015 (R0 == Mips::A0 && R1 == Mips::A1) ||
1016 (R0 == Mips::A0 && R1 == Mips::A2) ||
1017 (R0 == Mips::A0 && R1 == Mips::A3))
1023 StringRef getToken() const {
1024 assert(Kind == k_Token && "Invalid access!");
1025 return StringRef(Tok.Data, Tok.Length);
1027 bool isRegPair() const { return Kind == k_RegPair; }
1029 unsigned getReg() const override {
1030 // As a special case until we sort out the definition of div/divu, pretend
1031 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1032 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1033 RegIdx.Kind & RegKind_GPR)
1034 return getGPR32Reg(); // FIXME: GPR64 too
1036 assert(Kind == k_PhysRegister && "Invalid access!");
1040 const MCExpr *getImm() const {
1041 assert((Kind == k_Immediate) && "Invalid access!");
1045 int64_t getConstantImm() const {
1046 const MCExpr *Val = getImm();
1047 return static_cast<const MCConstantExpr *>(Val)->getValue();
1050 MipsOperand *getMemBase() const {
1051 assert((Kind == k_Memory) && "Invalid access!");
1055 const MCExpr *getMemOff() const {
1056 assert((Kind == k_Memory) && "Invalid access!");
1060 int64_t getConstantMemOff() const {
1061 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1064 const SmallVectorImpl<unsigned> &getRegList() const {
1065 assert((Kind == k_RegList) && "Invalid access!");
1066 return *(RegList.List);
1069 unsigned getRegPair() const {
1070 assert((Kind == k_RegPair) && "Invalid access!");
1071 return RegIdx.Index;
1074 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1075 MipsAsmParser &Parser) {
1076 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1077 Op->Tok.Data = Str.data();
1078 Op->Tok.Length = Str.size();
1084 /// Create a numeric register (e.g. $1). The exact register remains
1085 /// unresolved until an instruction successfully matches
1086 static std::unique_ptr<MipsOperand>
1087 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1088 SMLoc E, MipsAsmParser &Parser) {
1089 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1090 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1093 /// Create a register that is definitely a GPR.
1094 /// This is typically only used for named registers such as $gp.
1095 static std::unique_ptr<MipsOperand>
1096 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1097 MipsAsmParser &Parser) {
1098 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1101 /// Create a register that is definitely a FGR.
1102 /// This is typically only used for named registers such as $f0.
1103 static std::unique_ptr<MipsOperand>
1104 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1105 MipsAsmParser &Parser) {
1106 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1109 /// Create a register that is definitely a HWReg.
1110 /// This is typically only used for named registers such as $hwr_cpunum.
1111 static std::unique_ptr<MipsOperand>
1112 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1113 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1114 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1117 /// Create a register that is definitely an FCC.
1118 /// This is typically only used for named registers such as $fcc0.
1119 static std::unique_ptr<MipsOperand>
1120 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1121 MipsAsmParser &Parser) {
1122 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1125 /// Create a register that is definitely an ACC.
1126 /// This is typically only used for named registers such as $ac0.
1127 static std::unique_ptr<MipsOperand>
1128 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1129 MipsAsmParser &Parser) {
1130 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1133 /// Create a register that is definitely an MSA128.
1134 /// This is typically only used for named registers such as $w0.
1135 static std::unique_ptr<MipsOperand>
1136 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1137 SMLoc E, MipsAsmParser &Parser) {
1138 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1141 /// Create a register that is definitely an MSACtrl.
1142 /// This is typically only used for named registers such as $msaaccess.
1143 static std::unique_ptr<MipsOperand>
1144 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1145 SMLoc E, MipsAsmParser &Parser) {
1146 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1149 static std::unique_ptr<MipsOperand>
1150 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1151 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1158 static std::unique_ptr<MipsOperand>
1159 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1160 SMLoc E, MipsAsmParser &Parser) {
1161 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1162 Op->Mem.Base = Base.release();
1169 static std::unique_ptr<MipsOperand>
1170 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1171 MipsAsmParser &Parser) {
1172 assert (Regs.size() > 0 && "Empty list not allowed");
1174 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1175 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1176 Op->StartLoc = StartLoc;
1177 Op->EndLoc = EndLoc;
1181 static std::unique_ptr<MipsOperand>
1182 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1183 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1184 Op->RegIdx.Index = RegNo;
1190 bool isGPRAsmReg() const {
1191 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1193 bool isMM16AsmReg() const {
1194 if (!(isRegIdx() && RegIdx.Kind))
1196 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1197 || RegIdx.Index == 16 || RegIdx.Index == 17);
1199 bool isMM16AsmRegZero() const {
1200 if (!(isRegIdx() && RegIdx.Kind))
1202 return (RegIdx.Index == 0 ||
1203 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1204 RegIdx.Index == 17);
1206 bool isMM16AsmRegMoveP() const {
1207 if (!(isRegIdx() && RegIdx.Kind))
1209 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1210 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1212 bool isFGRAsmReg() const {
1213 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1214 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1216 bool isHWRegsAsmReg() const {
1217 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1219 bool isCCRAsmReg() const {
1220 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1222 bool isFCCAsmReg() const {
1223 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1225 if (!AsmParser.hasEightFccRegisters())
1226 return RegIdx.Index == 0;
1227 return RegIdx.Index <= 7;
1229 bool isACCAsmReg() const {
1230 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1232 bool isCOP0AsmReg() const {
1233 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1235 bool isCOP2AsmReg() const {
1236 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1238 bool isCOP3AsmReg() const {
1239 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1241 bool isMSA128AsmReg() const {
1242 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1244 bool isMSACtrlAsmReg() const {
1245 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1248 /// getStartLoc - Get the location of the first token of this operand.
1249 SMLoc getStartLoc() const override { return StartLoc; }
1250 /// getEndLoc - Get the location of the last token of this operand.
1251 SMLoc getEndLoc() const override { return EndLoc; }
1253 virtual ~MipsOperand() {
1261 delete RegList.List;
1262 case k_PhysRegister:
1263 case k_RegisterIndex:
1270 void print(raw_ostream &OS) const override {
1279 Mem.Base->print(OS);
1284 case k_PhysRegister:
1285 OS << "PhysReg<" << PhysReg.Num << ">";
1287 case k_RegisterIndex:
1288 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1295 for (auto Reg : (*RegList.List))
1300 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1304 }; // class MipsOperand
1308 extern const MCInstrDesc MipsInsts[];
1310 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1311 return MipsInsts[Opcode];
1314 static bool hasShortDelaySlot(unsigned Opcode) {
1317 case Mips::JALRS_MM:
1318 case Mips::JALRS16_MM:
1319 case Mips::BGEZALS_MM:
1320 case Mips::BLTZALS_MM:
1327 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1328 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1329 return &SRExpr->getSymbol();
1332 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1333 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1334 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1345 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1346 return getSingleMCSymbol(UExpr->getSubExpr());
1351 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1352 if (isa<MCSymbolRefExpr>(Expr))
1355 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1356 return countMCSymbolRefExpr(BExpr->getLHS()) +
1357 countMCSymbolRefExpr(BExpr->getRHS());
1359 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1360 return countMCSymbolRefExpr(UExpr->getSubExpr());
1365 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1366 SmallVectorImpl<MCInst> &Instructions) {
1367 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1368 bool ExpandedJalSym = false;
1372 if (MCID.isBranch() || MCID.isCall()) {
1373 const unsigned Opcode = Inst.getOpcode();
1383 assert(hasCnMips() && "instruction only valid for octeon cpus");
1390 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1391 Offset = Inst.getOperand(2);
1392 if (!Offset.isImm())
1393 break; // We'll deal with this situation later on when applying fixups.
1394 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1395 return Error(IDLoc, "branch target out of range");
1396 if (OffsetToAlignment(Offset.getImm(),
1397 1LL << (inMicroMipsMode() ? 1 : 2)))
1398 return Error(IDLoc, "branch to misaligned address");
1412 case Mips::BGEZAL_MM:
1413 case Mips::BLTZAL_MM:
1416 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1417 Offset = Inst.getOperand(1);
1418 if (!Offset.isImm())
1419 break; // We'll deal with this situation later on when applying fixups.
1420 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1421 return Error(IDLoc, "branch target out of range");
1422 if (OffsetToAlignment(Offset.getImm(),
1423 1LL << (inMicroMipsMode() ? 1 : 2)))
1424 return Error(IDLoc, "branch to misaligned address");
1426 case Mips::BEQZ16_MM:
1427 case Mips::BEQZC16_MMR6:
1428 case Mips::BNEZ16_MM:
1429 case Mips::BNEZC16_MMR6:
1430 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1431 Offset = Inst.getOperand(1);
1432 if (!Offset.isImm())
1433 break; // We'll deal with this situation later on when applying fixups.
1434 if (!isIntN(8, Offset.getImm()))
1435 return Error(IDLoc, "branch target out of range");
1436 if (OffsetToAlignment(Offset.getImm(), 2LL))
1437 return Error(IDLoc, "branch to misaligned address");
1442 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1443 // We still accept it but it is a normal nop.
1444 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1445 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1446 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1451 const unsigned Opcode = Inst.getOpcode();
1463 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1464 // The offset is handled above
1465 Opnd = Inst.getOperand(1);
1467 return Error(IDLoc, "expected immediate operand kind");
1468 Imm = Opnd.getImm();
1469 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1470 Opcode == Mips::BBIT1 ? 63 : 31))
1471 return Error(IDLoc, "immediate operand value out of range");
1473 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1475 Inst.getOperand(1).setImm(Imm - 32);
1483 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1485 Opnd = Inst.getOperand(3);
1487 return Error(IDLoc, "expected immediate operand kind");
1488 Imm = Opnd.getImm();
1489 if (Imm < 0 || Imm > 31)
1490 return Error(IDLoc, "immediate operand value out of range");
1492 Opnd = Inst.getOperand(2);
1494 return Error(IDLoc, "expected immediate operand kind");
1495 Imm = Opnd.getImm();
1496 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1497 Opcode == Mips::EXTS ? 63 : 31))
1498 return Error(IDLoc, "immediate operand value out of range");
1500 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1501 Inst.getOperand(2).setImm(Imm - 32);
1507 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1508 Opnd = Inst.getOperand(2);
1510 return Error(IDLoc, "expected immediate operand kind");
1511 Imm = Opnd.getImm();
1512 if (!isInt<10>(Imm))
1513 return Error(IDLoc, "immediate operand value out of range");
1518 // This expansion is not in a function called by expandInstruction() because
1519 // the pseudo-instruction doesn't have a distinct opcode.
1520 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1522 warnIfNoMacro(IDLoc);
1524 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1526 // We can do this expansion if there's only 1 symbol in the argument
1528 if (countMCSymbolRefExpr(JalExpr) > 1)
1529 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1531 // FIXME: This is checking the expression can be handled by the later stages
1532 // of the assembler. We ought to leave it to those later stages but
1533 // we can't do that until we stop evaluateRelocExpr() rewriting the
1534 // expressions into non-equivalent forms.
1535 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1537 // FIXME: Add support for label+offset operands (currently causes an error).
1538 // FIXME: Add support for forward-declared local symbols.
1539 // FIXME: Add expansion for when the LargeGOT option is enabled.
1540 if (JalSym->isInSection() || JalSym->isTemporary()) {
1542 // If it's a local symbol and the O32 ABI is being used, we expand to:
1544 // R_(MICRO)MIPS_GOT16 label
1545 // addiu $25, $25, 0
1546 // R_(MICRO)MIPS_LO16 label
1548 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1549 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1552 LwInst.setOpcode(Mips::LW);
1553 LwInst.addOperand(MCOperand::createReg(Mips::T9));
1554 LwInst.addOperand(MCOperand::createReg(Mips::GP));
1555 LwInst.addOperand(MCOperand::createExpr(Got16RelocExpr));
1556 Instructions.push_back(LwInst);
1559 AddiuInst.setOpcode(Mips::ADDiu);
1560 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1561 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1562 AddiuInst.addOperand(MCOperand::createExpr(Lo16RelocExpr));
1563 Instructions.push_back(AddiuInst);
1564 } else if (isABI_N32() || isABI_N64()) {
1565 // If it's a local symbol and the N32/N64 ABIs are being used,
1567 // lw/ld $25, 0($gp)
1568 // R_(MICRO)MIPS_GOT_DISP label
1570 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1573 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1574 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1575 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1576 LoadInst.addOperand(MCOperand::createExpr(GotDispRelocExpr));
1577 Instructions.push_back(LoadInst);
1580 // If it's an external/weak symbol, we expand to:
1581 // lw/ld $25, 0($gp)
1582 // R_(MICRO)MIPS_CALL16 label
1584 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1587 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1588 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1589 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1590 LoadInst.addOperand(MCOperand::createExpr(Call16RelocExpr));
1591 Instructions.push_back(LoadInst);
1595 if (IsCpRestoreSet && inMicroMipsMode())
1596 JalrInst.setOpcode(Mips::JALRS_MM);
1598 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1599 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1600 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1602 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1603 // This relocation is supposed to be an optimization hint for the linker
1604 // and is not necessary for correctness.
1607 ExpandedJalSym = true;
1610 if (MCID.mayLoad() || MCID.mayStore()) {
1611 // Check the offset of memory operand, if it is a symbol
1612 // reference or immediate we may have to expand instructions.
1613 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1614 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1615 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1616 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1617 MCOperand &Op = Inst.getOperand(i);
1619 int MemOffset = Op.getImm();
1620 if (MemOffset < -32768 || MemOffset > 32767) {
1621 // Offset can't exceed 16bit value.
1622 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1625 } else if (Op.isExpr()) {
1626 const MCExpr *Expr = Op.getExpr();
1627 if (Expr->getKind() == MCExpr::SymbolRef) {
1628 const MCSymbolRefExpr *SR =
1629 static_cast<const MCSymbolRefExpr *>(Expr);
1630 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1632 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1635 } else if (!isEvaluated(Expr)) {
1636 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1644 if (inMicroMipsMode()) {
1645 if (MCID.mayLoad()) {
1646 // Try to create 16-bit GP relative load instruction.
1647 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1648 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1649 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1650 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1651 MCOperand &Op = Inst.getOperand(i);
1653 int MemOffset = Op.getImm();
1654 MCOperand &DstReg = Inst.getOperand(0);
1655 MCOperand &BaseReg = Inst.getOperand(1);
1656 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1657 getContext().getRegisterInfo()->getRegClass(
1658 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1659 (BaseReg.getReg() == Mips::GP ||
1660 BaseReg.getReg() == Mips::GP_64)) {
1662 TmpInst.setLoc(IDLoc);
1663 TmpInst.setOpcode(Mips::LWGP_MM);
1664 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1665 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1666 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1667 Instructions.push_back(TmpInst);
1675 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1680 switch (Inst.getOpcode()) {
1683 case Mips::ADDIUS5_MM:
1684 Opnd = Inst.getOperand(2);
1686 return Error(IDLoc, "expected immediate operand kind");
1687 Imm = Opnd.getImm();
1688 if (Imm < -8 || Imm > 7)
1689 return Error(IDLoc, "immediate operand value out of range");
1691 case Mips::ADDIUSP_MM:
1692 Opnd = Inst.getOperand(0);
1694 return Error(IDLoc, "expected immediate operand kind");
1695 Imm = Opnd.getImm();
1696 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1698 return Error(IDLoc, "immediate operand value out of range");
1700 case Mips::SLL16_MM:
1701 case Mips::SRL16_MM:
1702 Opnd = Inst.getOperand(2);
1704 return Error(IDLoc, "expected immediate operand kind");
1705 Imm = Opnd.getImm();
1706 if (Imm < 1 || Imm > 8)
1707 return Error(IDLoc, "immediate operand value out of range");
1710 Opnd = Inst.getOperand(1);
1712 return Error(IDLoc, "expected immediate operand kind");
1713 Imm = Opnd.getImm();
1714 if (Imm < -1 || Imm > 126)
1715 return Error(IDLoc, "immediate operand value out of range");
1717 case Mips::ADDIUR2_MM:
1718 Opnd = Inst.getOperand(2);
1720 return Error(IDLoc, "expected immediate operand kind");
1721 Imm = Opnd.getImm();
1722 if (!(Imm == 1 || Imm == -1 ||
1723 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1724 return Error(IDLoc, "immediate operand value out of range");
1726 case Mips::ADDIUR1SP_MM:
1727 Opnd = Inst.getOperand(1);
1729 return Error(IDLoc, "expected immediate operand kind");
1730 Imm = Opnd.getImm();
1731 if (OffsetToAlignment(Imm, 4LL))
1732 return Error(IDLoc, "misaligned immediate operand value");
1733 if (Imm < 0 || Imm > 255)
1734 return Error(IDLoc, "immediate operand value out of range");
1736 case Mips::ANDI16_MM:
1737 Opnd = Inst.getOperand(2);
1739 return Error(IDLoc, "expected immediate operand kind");
1740 Imm = Opnd.getImm();
1741 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1742 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1743 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1744 return Error(IDLoc, "immediate operand value out of range");
1746 case Mips::LBU16_MM:
1747 Opnd = Inst.getOperand(2);
1749 return Error(IDLoc, "expected immediate operand kind");
1750 Imm = Opnd.getImm();
1751 if (Imm < -1 || Imm > 14)
1752 return Error(IDLoc, "immediate operand value out of range");
1761 Opnd = Inst.getOperand(2);
1763 return Error(IDLoc, "expected immediate operand kind");
1764 Imm = Opnd.getImm();
1765 if (Imm < 0 || Imm > 15)
1766 return Error(IDLoc, "immediate operand value out of range");
1768 case Mips::LHU16_MM:
1770 Opnd = Inst.getOperand(2);
1772 return Error(IDLoc, "expected immediate operand kind");
1773 Imm = Opnd.getImm();
1774 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1775 return Error(IDLoc, "immediate operand value out of range");
1779 Opnd = Inst.getOperand(2);
1781 return Error(IDLoc, "expected immediate operand kind");
1782 Imm = Opnd.getImm();
1783 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1784 return Error(IDLoc, "immediate operand value out of range");
1786 case Mips::PREFX_MM:
1789 Opnd = Inst.getOperand(2);
1791 return Error(IDLoc, "expected immediate operand kind");
1792 Imm = Opnd.getImm();
1793 if (!isUInt<5>(Imm))
1794 return Error(IDLoc, "immediate operand value out of range");
1796 case Mips::ADDIUPC_MM:
1797 MCOperand Opnd = Inst.getOperand(1);
1799 return Error(IDLoc, "expected immediate operand kind");
1800 int Imm = Opnd.getImm();
1801 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1802 return Error(IDLoc, "immediate operand value out of range");
1807 if (needsExpansion(Inst)) {
1808 if (expandInstruction(Inst, IDLoc, Instructions))
1811 Instructions.push_back(Inst);
1813 // If this instruction has a delay slot and .set reorder is active,
1814 // emit a NOP after it.
1815 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1816 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1818 if ((Inst.getOpcode() == Mips::JalOneReg ||
1819 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1820 isPicAndNotNxxAbi()) {
1821 if (IsCpRestoreSet) {
1822 // We need a NOP between the JALR and the LW:
1823 // If .set reorder has been used, we've already emitted a NOP.
1824 // If .set noreorder has been used, we need to emit a NOP at this point.
1825 if (!AssemblerOptions.back()->isReorder())
1826 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1828 // Load the $gp from the stack.
1829 SmallVector<MCInst, 3> LoadInsts;
1830 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1833 for (const MCInst &Inst : LoadInsts)
1834 Instructions.push_back(Inst);
1837 Warning(IDLoc, "no .cprestore used in PIC mode");
1843 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1845 switch (Inst.getOpcode()) {
1846 case Mips::LoadImm32:
1847 case Mips::LoadImm64:
1848 case Mips::LoadAddrImm32:
1849 case Mips::LoadAddrImm64:
1850 case Mips::LoadAddrReg32:
1851 case Mips::LoadAddrReg64:
1852 case Mips::B_MM_Pseudo:
1853 case Mips::B_MMR6_Pseudo:
1856 case Mips::JalOneReg:
1857 case Mips::JalTwoReg:
1876 case Mips::SDivMacro:
1877 case Mips::UDivMacro:
1878 case Mips::DSDivMacro:
1879 case Mips::DUDivMacro:
1888 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1889 SmallVectorImpl<MCInst> &Instructions) {
1890 switch (Inst.getOpcode()) {
1891 default: llvm_unreachable("unimplemented expansion");
1892 case Mips::LoadImm32:
1893 return expandLoadImm(Inst, true, IDLoc, Instructions);
1894 case Mips::LoadImm64:
1895 return expandLoadImm(Inst, false, IDLoc, Instructions);
1896 case Mips::LoadAddrImm32:
1897 case Mips::LoadAddrImm64:
1898 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1899 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1900 "expected immediate operand kind");
1902 return expandLoadAddress(
1903 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1904 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1905 case Mips::LoadAddrReg32:
1906 case Mips::LoadAddrReg64:
1907 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1908 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1909 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1910 "expected immediate operand kind");
1912 return expandLoadAddress(
1913 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1914 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1915 case Mips::B_MM_Pseudo:
1916 case Mips::B_MMR6_Pseudo:
1917 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1920 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1921 case Mips::JalOneReg:
1922 case Mips::JalTwoReg:
1923 return expandJalWithRegs(Inst, IDLoc, Instructions);
1926 return expandBranchImm(Inst, IDLoc, Instructions);
1943 return expandCondBranches(Inst, IDLoc, Instructions);
1944 case Mips::SDivMacro:
1945 return expandDiv(Inst, IDLoc, Instructions, false, true);
1946 case Mips::DSDivMacro:
1947 return expandDiv(Inst, IDLoc, Instructions, true, true);
1948 case Mips::UDivMacro:
1949 return expandDiv(Inst, IDLoc, Instructions, false, false);
1950 case Mips::DUDivMacro:
1951 return expandDiv(Inst, IDLoc, Instructions, true, false);
1953 return expandUlhu(Inst, IDLoc, Instructions);
1955 return expandUlw(Inst, IDLoc, Instructions);
1960 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1961 SmallVectorImpl<MCInst> &Instructions) {
1963 tmpInst.setOpcode(Opcode);
1964 tmpInst.addOperand(MCOperand::createReg(Reg0));
1965 tmpInst.addOperand(Op1);
1966 tmpInst.setLoc(IDLoc);
1967 Instructions.push_back(tmpInst);
1970 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1971 SmallVectorImpl<MCInst> &Instructions) {
1972 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1975 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1976 SmallVectorImpl<MCInst> &Instructions) {
1977 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1980 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1981 SmallVectorImpl<MCInst> &Instructions) {
1983 tmpInst.setOpcode(Opcode);
1984 tmpInst.addOperand(MCOperand::createImm(Imm1));
1985 tmpInst.addOperand(MCOperand::createImm(Imm2));
1986 tmpInst.setLoc(IDLoc);
1987 Instructions.push_back(tmpInst);
1990 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1991 SmallVectorImpl<MCInst> &Instructions) {
1993 tmpInst.setOpcode(Opcode);
1994 tmpInst.addOperand(MCOperand::createReg(Reg0));
1995 tmpInst.setLoc(IDLoc);
1996 Instructions.push_back(tmpInst);
1999 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
2000 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2002 tmpInst.setOpcode(Opcode);
2003 tmpInst.addOperand(MCOperand::createReg(Reg0));
2004 tmpInst.addOperand(MCOperand::createReg(Reg1));
2005 tmpInst.addOperand(Op2);
2006 tmpInst.setLoc(IDLoc);
2007 Instructions.push_back(tmpInst);
2010 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
2011 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2012 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
2016 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
2017 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2018 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
2022 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
2023 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2024 if (ShiftAmount >= 32) {
2025 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
2030 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
2032 } // end anonymous namespace.
2034 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2035 SmallVectorImpl<MCInst> &Instructions) {
2036 // Create a JALR instruction which is going to replace the pseudo-JAL.
2038 JalrInst.setLoc(IDLoc);
2039 const MCOperand FirstRegOp = Inst.getOperand(0);
2040 const unsigned Opcode = Inst.getOpcode();
2042 if (Opcode == Mips::JalOneReg) {
2043 // jal $rs => jalr $rs
2044 if (IsCpRestoreSet && inMicroMipsMode()) {
2045 JalrInst.setOpcode(Mips::JALRS16_MM);
2046 JalrInst.addOperand(FirstRegOp);
2047 } else if (inMicroMipsMode()) {
2048 JalrInst.setOpcode(Mips::JALR16_MM);
2049 JalrInst.addOperand(FirstRegOp);
2051 JalrInst.setOpcode(Mips::JALR);
2052 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2053 JalrInst.addOperand(FirstRegOp);
2055 } else if (Opcode == Mips::JalTwoReg) {
2056 // jal $rd, $rs => jalr $rd, $rs
2057 if (IsCpRestoreSet && inMicroMipsMode())
2058 JalrInst.setOpcode(Mips::JALRS_MM);
2060 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2061 JalrInst.addOperand(FirstRegOp);
2062 const MCOperand SecondRegOp = Inst.getOperand(1);
2063 JalrInst.addOperand(SecondRegOp);
2065 Instructions.push_back(JalrInst);
2067 // If .set reorder is active, emit a NOP after it.
2068 if (AssemblerOptions.back()->isReorder())
2069 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2074 /// Can the value be represented by a unsigned N-bit value and a shift left?
2075 template<unsigned N>
2076 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2077 unsigned BitNum = findFirstSet(x);
2079 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2082 /// Load (or add) an immediate into a register.
2084 /// @param ImmValue The immediate to load.
2085 /// @param DstReg The register that will hold the immediate.
2086 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2087 /// for a simple initialization.
2088 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2089 /// @param IsAddress True if the immediate represents an address. False if it
2091 /// @param IDLoc Location of the immediate in the source file.
2092 /// @param Instructions The instructions emitted by this expansion.
2093 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2094 unsigned SrcReg, bool Is32BitImm,
2095 bool IsAddress, SMLoc IDLoc,
2096 SmallVectorImpl<MCInst> &Instructions) {
2097 if (!Is32BitImm && !isGP64bit()) {
2098 Error(IDLoc, "instruction requires a 64-bit architecture");
2103 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2104 // Sign extend up to 64-bit so that the predicates match the hardware
2105 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2107 ImmValue = SignExtend64<32>(ImmValue);
2109 Error(IDLoc, "instruction requires a 32-bit immediate");
2114 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2115 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2117 bool UseSrcReg = false;
2118 if (SrcReg != Mips::NoRegister)
2121 unsigned TmpReg = DstReg;
2122 if (UseSrcReg && (DstReg == SrcReg)) {
2123 // At this point we need AT to perform the expansions and we exit if it is
2125 unsigned ATReg = getATReg(IDLoc);
2131 if (isInt<16>(ImmValue)) {
2135 // This doesn't quite follow the usual ABI expectations for N32 but matches
2136 // traditional assembler behaviour. N32 would normally use addiu for both
2137 // integers and addresses.
2138 if (IsAddress && !Is32BitImm) {
2139 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2143 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2147 if (isUInt<16>(ImmValue)) {
2148 unsigned TmpReg = DstReg;
2149 if (SrcReg == DstReg) {
2150 TmpReg = getATReg(IDLoc);
2155 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2157 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2161 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2162 warnIfNoMacro(IDLoc);
2164 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2165 uint16_t Bits15To0 = ImmValue & 0xffff;
2167 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2168 // Traditional behaviour seems to special case this particular value. It's
2169 // not clear why other masks are handled differently.
2170 if (ImmValue == 0xffffffff) {
2171 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2172 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2174 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2178 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2180 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2181 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2183 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2185 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2189 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2191 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2193 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2197 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2199 Error(IDLoc, "instruction requires a 32-bit immediate");
2203 // Traditionally, these immediates are shifted as little as possible and as
2204 // such we align the most significant bit to bit 15 of our temporary.
2205 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2206 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2207 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2208 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2209 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2210 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2213 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2218 warnIfNoMacro(IDLoc);
2220 // The remaining case is packed with a sequence of dsll and ori with zeros
2221 // being omitted and any neighbouring dsll's being coalesced.
2222 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2224 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2225 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2226 IDLoc, Instructions))
2229 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2230 // skip it and defer the shift to the next chunk.
2231 unsigned ShiftCarriedForwards = 16;
2232 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2233 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2235 if (ImmChunk != 0) {
2236 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2238 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2239 ShiftCarriedForwards = 0;
2242 ShiftCarriedForwards += 16;
2244 ShiftCarriedForwards -= 16;
2246 // Finish any remaining shifts left by trailing zeros.
2247 if (ShiftCarriedForwards)
2248 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2252 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2257 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2258 SmallVectorImpl<MCInst> &Instructions) {
2259 const MCOperand &ImmOp = Inst.getOperand(1);
2260 assert(ImmOp.isImm() && "expected immediate operand kind");
2261 const MCOperand &DstRegOp = Inst.getOperand(0);
2262 assert(DstRegOp.isReg() && "expected register operand kind");
2264 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2265 Is32BitImm, false, IDLoc, Instructions))
2271 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2272 const MCOperand &Offset,
2273 bool Is32BitAddress, SMLoc IDLoc,
2274 SmallVectorImpl<MCInst> &Instructions) {
2275 // la can't produce a usable address when addresses are 64-bit.
2276 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2277 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2278 // We currently can't do this because we depend on the equality
2279 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2280 Error(IDLoc, "la used to load 64-bit address");
2281 // Continue as if we had 'dla' instead.
2282 Is32BitAddress = false;
2285 // dla requires 64-bit addresses.
2286 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2287 Error(IDLoc, "instruction requires a 64-bit architecture");
2291 if (!Offset.isImm())
2292 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2293 Is32BitAddress, IDLoc, Instructions);
2295 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2296 IDLoc, Instructions);
2299 bool MipsAsmParser::loadAndAddSymbolAddress(
2300 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2301 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2302 warnIfNoMacro(IDLoc);
2304 // FIXME: The way we're handling symbols right now prevents simple expressions
2305 // like foo+8. We'll be able to fix this once our unary operators (%hi
2306 // and similar) are treated as operators rather than as fixup types.
2307 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2308 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2309 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2310 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2311 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2313 bool UseSrcReg = SrcReg != Mips::NoRegister;
2315 // This is the 64-bit symbol address expansion.
2316 if (ABI.ArePtrs64bit() && isGP64bit()) {
2317 // We always need AT for the 64-bit expansion.
2318 // If it is not available we exit.
2319 unsigned ATReg = getATReg(IDLoc);
2323 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2324 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2325 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2326 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2328 if (UseSrcReg && (DstReg == SrcReg)) {
2329 // If $rs is the same as $rd:
2330 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2331 // daddiu $at, $at, %higher(sym)
2332 // dsll $at, $at, 16
2333 // daddiu $at, $at, %hi(sym)
2334 // dsll $at, $at, 16
2335 // daddiu $at, $at, %lo(sym)
2336 // daddu $rd, $at, $rd
2337 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2339 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2340 IDLoc, Instructions);
2341 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2342 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2344 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2345 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2347 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2352 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2353 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2354 // lui $at, %hi(sym)
2355 // daddiu $rd, $rd, %higher(sym)
2356 // daddiu $at, $at, %lo(sym)
2357 // dsll32 $rd, $rd, 0
2358 // daddu $rd, $rd, $at
2359 // (daddu $rd, $rd, $rs)
2360 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2362 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2364 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2365 IDLoc, Instructions);
2366 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2368 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2369 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2371 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2376 // And now, the 32-bit symbol address expansion:
2377 // If $rs is the same as $rd:
2378 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2379 // ori $at, $at, %lo(sym)
2380 // addu $rd, $at, $rd
2381 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2382 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2383 // ori $rd, $rd, %lo(sym)
2384 // (addu $rd, $rd, $rs)
2385 unsigned TmpReg = DstReg;
2386 if (UseSrcReg && (DstReg == SrcReg)) {
2387 // If $rs is the same as $rd, we need to use AT.
2388 // If it is not available we exit.
2389 unsigned ATReg = getATReg(IDLoc);
2395 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2396 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2400 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2402 assert(DstReg == TmpReg);
2407 bool MipsAsmParser::expandUncondBranchMMPseudo(
2408 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2409 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2410 "unexpected number of operands");
2412 MCOperand Offset = Inst.getOperand(0);
2413 if (Offset.isExpr()) {
2415 Inst.setOpcode(Mips::BEQ_MM);
2416 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2417 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2418 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2420 assert(Offset.isImm() && "expected immediate operand kind");
2421 if (isIntN(11, Offset.getImm())) {
2422 // If offset fits into 11 bits then this instruction becomes microMIPS
2423 // 16-bit unconditional branch instruction.
2424 if (inMicroMipsMode())
2425 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2427 if (!isIntN(17, Offset.getImm()))
2428 Error(IDLoc, "branch target out of range");
2429 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2430 Error(IDLoc, "branch to misaligned address");
2432 Inst.setOpcode(Mips::BEQ_MM);
2433 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2434 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2435 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2438 Instructions.push_back(Inst);
2440 // If .set reorder is active and branch instruction has a delay slot,
2441 // emit a NOP after it.
2442 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2443 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2444 createNop(true, IDLoc, Instructions);
2449 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2450 SmallVectorImpl<MCInst> &Instructions) {
2451 const MCOperand &DstRegOp = Inst.getOperand(0);
2452 assert(DstRegOp.isReg() && "expected register operand kind");
2454 const MCOperand &ImmOp = Inst.getOperand(1);
2455 assert(ImmOp.isImm() && "expected immediate operand kind");
2457 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2458 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2460 unsigned OpCode = 0;
2461 switch(Inst.getOpcode()) {
2469 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2473 int64_t ImmValue = ImmOp.getImm();
2474 if (ImmValue == 0) {
2476 BranchInst.setOpcode(OpCode);
2477 BranchInst.addOperand(DstRegOp);
2478 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2479 BranchInst.addOperand(MemOffsetOp);
2480 Instructions.push_back(BranchInst);
2482 warnIfNoMacro(IDLoc);
2484 unsigned ATReg = getATReg(IDLoc);
2488 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2489 IDLoc, Instructions))
2493 BranchInst.setOpcode(OpCode);
2494 BranchInst.addOperand(DstRegOp);
2495 BranchInst.addOperand(MCOperand::createReg(ATReg));
2496 BranchInst.addOperand(MemOffsetOp);
2497 Instructions.push_back(BranchInst);
2502 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2503 SmallVectorImpl<MCInst> &Instructions,
2504 bool isLoad, bool isImmOpnd) {
2506 unsigned ImmOffset, HiOffset, LoOffset;
2507 const MCExpr *ExprOffset;
2509 // 1st operand is either the source or destination register.
2510 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2511 unsigned RegOpNum = Inst.getOperand(0).getReg();
2512 // 2nd operand is the base register.
2513 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2514 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2515 // 3rd operand is either an immediate or expression.
2517 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2518 ImmOffset = Inst.getOperand(2).getImm();
2519 LoOffset = ImmOffset & 0x0000ffff;
2520 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2521 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2522 if (LoOffset & 0x8000)
2525 ExprOffset = Inst.getOperand(2).getExpr();
2526 // All instructions will have the same location.
2527 TempInst.setLoc(IDLoc);
2528 // These are some of the types of expansions we perform here:
2529 // 1) lw $8, sym => lui $8, %hi(sym)
2530 // lw $8, %lo(sym)($8)
2531 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2533 // lw $8, %lo(offset)($9)
2534 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2536 // lw $8, %lo(offset)($at)
2537 // 4) sw $8, sym => lui $at, %hi(sym)
2538 // sw $8, %lo(sym)($at)
2539 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2541 // sw $8, %lo(offset)($at)
2542 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2543 // ldc1 $f0, %lo(sym)($at)
2545 // For load instructions we can use the destination register as a temporary
2546 // if base and dst are different (examples 1 and 2) and if the base register
2547 // is general purpose otherwise we must use $at (example 6) and error if it's
2548 // not available. For stores we must use $at (examples 4 and 5) because we
2549 // must not clobber the source register setting up the offset.
2550 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2551 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2552 unsigned RegClassIDOp0 =
2553 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2554 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2555 (RegClassIDOp0 == Mips::GPR64RegClassID);
2556 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2557 TmpRegNum = RegOpNum;
2559 // At this point we need AT to perform the expansions and we exit if it is
2561 TmpRegNum = getATReg(IDLoc);
2566 TempInst.setOpcode(Mips::LUi);
2567 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2569 TempInst.addOperand(MCOperand::createImm(HiOffset));
2571 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2572 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2574 // Add the instruction to the list.
2575 Instructions.push_back(TempInst);
2576 // Prepare TempInst for next instruction.
2578 // Add temp register to base.
2579 if (BaseRegNum != Mips::ZERO) {
2580 TempInst.setOpcode(Mips::ADDu);
2581 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2582 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2583 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2584 Instructions.push_back(TempInst);
2587 // And finally, create original instruction with low part
2588 // of offset and new base.
2589 TempInst.setOpcode(Inst.getOpcode());
2590 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2591 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2593 TempInst.addOperand(MCOperand::createImm(LoOffset));
2595 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2596 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2598 Instructions.push_back(TempInst);
2603 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2604 SmallVectorImpl<MCInst> &Instructions) {
2605 unsigned OpNum = Inst.getNumOperands();
2606 unsigned Opcode = Inst.getOpcode();
2607 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2609 assert (Inst.getOperand(OpNum - 1).isImm() &&
2610 Inst.getOperand(OpNum - 2).isReg() &&
2611 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2613 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2614 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2615 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2616 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2617 // It can be implemented as SWM16 or LWM16 instruction.
2618 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2620 Inst.setOpcode(NewOpcode);
2621 Instructions.push_back(Inst);
2625 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2626 SmallVectorImpl<MCInst> &Instructions) {
2627 unsigned PseudoOpcode = Inst.getOpcode();
2628 unsigned SrcReg = Inst.getOperand(0).getReg();
2629 unsigned TrgReg = Inst.getOperand(1).getReg();
2630 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2632 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2633 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2635 switch (PseudoOpcode) {
2640 AcceptsEquality = false;
2641 ReverseOrderSLT = false;
2642 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2643 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2644 ZeroSrcOpcode = Mips::BGTZ;
2645 ZeroTrgOpcode = Mips::BLTZ;
2651 AcceptsEquality = true;
2652 ReverseOrderSLT = true;
2653 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2654 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2655 ZeroSrcOpcode = Mips::BGEZ;
2656 ZeroTrgOpcode = Mips::BLEZ;
2662 AcceptsEquality = true;
2663 ReverseOrderSLT = false;
2664 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2665 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2666 ZeroSrcOpcode = Mips::BLEZ;
2667 ZeroTrgOpcode = Mips::BGEZ;
2673 AcceptsEquality = false;
2674 ReverseOrderSLT = true;
2675 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2676 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2677 ZeroSrcOpcode = Mips::BLTZ;
2678 ZeroTrgOpcode = Mips::BGTZ;
2681 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2685 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2686 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2687 if (IsSrcRegZero && IsTrgRegZero) {
2688 // FIXME: All of these Opcode-specific if's are needed for compatibility
2689 // with GAS' behaviour. However, they may not generate the most efficient
2690 // code in some circumstances.
2691 if (PseudoOpcode == Mips::BLT) {
2692 BranchInst.setOpcode(Mips::BLTZ);
2693 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2694 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2695 Instructions.push_back(BranchInst);
2698 if (PseudoOpcode == Mips::BLE) {
2699 BranchInst.setOpcode(Mips::BLEZ);
2700 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2701 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2702 Instructions.push_back(BranchInst);
2703 Warning(IDLoc, "branch is always taken");
2706 if (PseudoOpcode == Mips::BGE) {
2707 BranchInst.setOpcode(Mips::BGEZ);
2708 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2709 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2710 Instructions.push_back(BranchInst);
2711 Warning(IDLoc, "branch is always taken");
2714 if (PseudoOpcode == Mips::BGT) {
2715 BranchInst.setOpcode(Mips::BGTZ);
2716 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2717 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2718 Instructions.push_back(BranchInst);
2721 if (PseudoOpcode == Mips::BGTU) {
2722 BranchInst.setOpcode(Mips::BNE);
2723 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2724 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2725 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2726 Instructions.push_back(BranchInst);
2729 if (AcceptsEquality) {
2730 // If both registers are $0 and the pseudo-branch accepts equality, it
2731 // will always be taken, so we emit an unconditional branch.
2732 BranchInst.setOpcode(Mips::BEQ);
2733 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2734 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2735 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2736 Instructions.push_back(BranchInst);
2737 Warning(IDLoc, "branch is always taken");
2740 // If both registers are $0 and the pseudo-branch does not accept
2741 // equality, it will never be taken, so we don't have to emit anything.
2744 if (IsSrcRegZero || IsTrgRegZero) {
2745 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2746 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2747 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2748 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2749 // the pseudo-branch will never be taken, so we don't emit anything.
2750 // This only applies to unsigned pseudo-branches.
2753 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2754 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2755 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2756 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2757 // the pseudo-branch will always be taken, so we emit an unconditional
2759 // This only applies to unsigned pseudo-branches.
2760 BranchInst.setOpcode(Mips::BEQ);
2761 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2762 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2763 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2764 Instructions.push_back(BranchInst);
2765 Warning(IDLoc, "branch is always taken");
2769 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2770 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2771 // the pseudo-branch will be taken only when the non-zero register is
2772 // different from 0, so we emit a BNEZ.
2774 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2775 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2776 // the pseudo-branch will be taken only when the non-zero register is
2777 // equal to 0, so we emit a BEQZ.
2779 // Because only BLEU and BGEU branch on equality, we can use the
2780 // AcceptsEquality variable to decide when to emit the BEQZ.
2781 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2782 BranchInst.addOperand(
2783 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2784 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2785 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2786 Instructions.push_back(BranchInst);
2789 // If we have a signed pseudo-branch and one of the registers is $0,
2790 // we can use an appropriate compare-to-zero branch. We select which one
2791 // to use in the switch statement above.
2792 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2793 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2794 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2795 Instructions.push_back(BranchInst);
2799 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2800 // expansions. If it is not available, we return.
2801 unsigned ATRegNum = getATReg(IDLoc);
2805 warnIfNoMacro(IDLoc);
2807 // SLT fits well with 2 of our 4 pseudo-branches:
2808 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2809 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2810 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2811 // This is accomplished by using a BNEZ with the result of the SLT.
2813 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2814 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2815 // Because only BGE and BLE branch on equality, we can use the
2816 // AcceptsEquality variable to decide when to emit the BEQZ.
2817 // Note that the order of the SLT arguments doesn't change between
2820 // The same applies to the unsigned variants, except that SLTu is used
2823 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2824 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2825 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2826 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2827 Instructions.push_back(SetInst);
2830 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2832 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQL : Mips::BNEL);
2833 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2834 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2835 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2836 Instructions.push_back(BranchInst);
2840 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2841 SmallVectorImpl<MCInst> &Instructions,
2842 const bool IsMips64, const bool Signed) {
2843 if (hasMips32r6()) {
2844 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2848 warnIfNoMacro(IDLoc);
2850 const MCOperand &RsRegOp = Inst.getOperand(0);
2851 assert(RsRegOp.isReg() && "expected register operand kind");
2852 unsigned RsReg = RsRegOp.getReg();
2854 const MCOperand &RtRegOp = Inst.getOperand(1);
2855 assert(RtRegOp.isReg() && "expected register operand kind");
2856 unsigned RtReg = RtRegOp.getReg();
2861 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2862 ZeroReg = Mips::ZERO_64;
2864 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2865 ZeroReg = Mips::ZERO;
2868 bool UseTraps = useTraps();
2870 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2871 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2872 Warning(IDLoc, "dividing zero by zero");
2874 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2876 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2880 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2884 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2889 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2890 Warning(IDLoc, "division by zero");
2893 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2897 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2902 // FIXME: The values for these two BranchTarget variables may be different in
2903 // micromips. These magic numbers need to be removed.
2904 unsigned BranchTargetNoTraps;
2905 unsigned BranchTarget;
2908 BranchTarget = IsMips64 ? 12 : 8;
2909 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2911 BranchTarget = IsMips64 ? 20 : 16;
2912 BranchTargetNoTraps = 8;
2913 // Branch to the li instruction.
2914 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2918 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2921 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2924 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2928 unsigned ATReg = getATReg(IDLoc);
2932 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2934 // Branch to the mflo instruction.
2935 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2936 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2937 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2939 // Branch to the mflo instruction.
2940 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2941 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2945 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2947 // Branch to the mflo instruction.
2948 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2949 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2950 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2952 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2956 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2957 SmallVectorImpl<MCInst> &Instructions) {
2958 if (hasMips32r6() || hasMips64r6()) {
2959 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2963 warnIfNoMacro(IDLoc);
2965 const MCOperand &DstRegOp = Inst.getOperand(0);
2966 assert(DstRegOp.isReg() && "expected register operand kind");
2968 const MCOperand &SrcRegOp = Inst.getOperand(1);
2969 assert(SrcRegOp.isReg() && "expected register operand kind");
2971 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2972 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2974 unsigned DstReg = DstRegOp.getReg();
2975 unsigned SrcReg = SrcRegOp.getReg();
2976 int64_t OffsetValue = OffsetImmOp.getImm();
2978 // NOTE: We always need AT for ULHU, as it is always used as the source
2979 // register for one of the LBu's.
2980 unsigned ATReg = getATReg(IDLoc);
2984 // When the value of offset+1 does not fit in 16 bits, we have to load the
2985 // offset in AT, (D)ADDu the original source register (if there was one), and
2986 // then use AT as the source register for the 2 generated LBu's.
2987 bool LoadedOffsetInAT = false;
2988 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2989 LoadedOffsetInAT = true;
2991 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2992 true, IDLoc, Instructions))
2995 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2996 // because it will make our output more similar to GAS'. For example,
2997 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2998 // instead of just an "ori $1, $9, 32768".
2999 // NOTE: If there is no source register specified in the ULHU, the parser
3000 // will interpret it as $0.
3001 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3002 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3005 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3006 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3007 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3009 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3011 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3012 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3014 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3015 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3018 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3021 TmpInst.setOpcode(Mips::LBu);
3022 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
3023 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
3024 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
3025 Instructions.push_back(TmpInst);
3028 TmpInst.setOpcode(Mips::LBu);
3029 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
3030 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
3031 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
3032 Instructions.push_back(TmpInst);
3035 TmpInst.setOpcode(Mips::SLL);
3036 TmpInst.addOperand(MCOperand::createReg(SllReg));
3037 TmpInst.addOperand(MCOperand::createReg(SllReg));
3038 TmpInst.addOperand(MCOperand::createImm(8));
3039 Instructions.push_back(TmpInst);
3042 TmpInst.setOpcode(Mips::OR);
3043 TmpInst.addOperand(MCOperand::createReg(DstReg));
3044 TmpInst.addOperand(MCOperand::createReg(DstReg));
3045 TmpInst.addOperand(MCOperand::createReg(ATReg));
3046 Instructions.push_back(TmpInst);
3051 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3052 SmallVectorImpl<MCInst> &Instructions) {
3053 if (hasMips32r6() || hasMips64r6()) {
3054 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3058 const MCOperand &DstRegOp = Inst.getOperand(0);
3059 assert(DstRegOp.isReg() && "expected register operand kind");
3061 const MCOperand &SrcRegOp = Inst.getOperand(1);
3062 assert(SrcRegOp.isReg() && "expected register operand kind");
3064 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3065 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3067 unsigned SrcReg = SrcRegOp.getReg();
3068 int64_t OffsetValue = OffsetImmOp.getImm();
3071 // When the value of offset+3 does not fit in 16 bits, we have to load the
3072 // offset in AT, (D)ADDu the original source register (if there was one), and
3073 // then use AT as the source register for the generated LWL and LWR.
3074 bool LoadedOffsetInAT = false;
3075 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3076 ATReg = getATReg(IDLoc);
3079 LoadedOffsetInAT = true;
3081 warnIfNoMacro(IDLoc);
3083 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3084 true, IDLoc, Instructions))
3087 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3088 // because it will make our output more similar to GAS'. For example,
3089 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3090 // instead of just an "ori $1, $9, 32768".
3091 // NOTE: If there is no source register specified in the ULW, the parser
3092 // will interpret it as $0.
3093 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3094 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3097 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3098 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3100 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3101 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3103 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3104 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3107 MCInst LeftLoadInst;
3108 LeftLoadInst.setOpcode(Mips::LWL);
3109 LeftLoadInst.addOperand(DstRegOp);
3110 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3111 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3112 Instructions.push_back(LeftLoadInst);
3114 MCInst RightLoadInst;
3115 RightLoadInst.setOpcode(Mips::LWR);
3116 RightLoadInst.addOperand(DstRegOp);
3117 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3118 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3119 Instructions.push_back(RightLoadInst);
3124 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3125 SmallVectorImpl<MCInst> &Instructions) {
3127 if (hasShortDelaySlot) {
3128 NopInst.setOpcode(Mips::MOVE16_MM);
3129 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3130 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3132 NopInst.setOpcode(Mips::SLL);
3133 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3134 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3135 NopInst.addOperand(MCOperand::createImm(0));
3137 Instructions.push_back(NopInst);
3140 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3141 unsigned TrgReg, bool Is64Bit,
3142 SmallVectorImpl<MCInst> &Instructions) {
3143 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3147 void MipsAsmParser::createCpRestoreMemOp(
3148 bool IsLoad, int StackOffset, SMLoc IDLoc,
3149 SmallVectorImpl<MCInst> &Instructions) {
3151 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3152 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3153 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3154 MemInst.addOperand(MCOperand::createImm(StackOffset));
3156 // If the offset can not fit into 16 bits, we need to expand.
3157 if (!isInt<16>(StackOffset))
3158 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3160 Instructions.push_back(MemInst);
3163 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3164 // As described by the Mips32r2 spec, the registers Rd and Rs for
3165 // jalr.hb must be different.
3166 unsigned Opcode = Inst.getOpcode();
3168 if (Opcode == Mips::JALR_HB &&
3169 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3170 return Match_RequiresDifferentSrcAndDst;
3172 return Match_Success;
3175 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3176 OperandVector &Operands,
3178 uint64_t &ErrorInfo,
3179 bool MatchingInlineAsm) {
3182 SmallVector<MCInst, 8> Instructions;
3183 unsigned MatchResult =
3184 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3186 switch (MatchResult) {
3187 case Match_Success: {
3188 if (processInstruction(Inst, IDLoc, Instructions))
3190 for (unsigned i = 0; i < Instructions.size(); i++)
3191 Out.EmitInstruction(Instructions[i], STI);
3194 case Match_MissingFeature:
3195 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3197 case Match_InvalidOperand: {
3198 SMLoc ErrorLoc = IDLoc;
3199 if (ErrorInfo != ~0ULL) {
3200 if (ErrorInfo >= Operands.size())
3201 return Error(IDLoc, "too few operands for instruction");
3203 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3204 if (ErrorLoc == SMLoc())
3208 return Error(ErrorLoc, "invalid operand for instruction");
3210 case Match_MnemonicFail:
3211 return Error(IDLoc, "invalid instruction");
3212 case Match_RequiresDifferentSrcAndDst:
3213 return Error(IDLoc, "source and destination must be different");
3216 llvm_unreachable("Implement any new match types added!");
3219 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3220 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3221 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3222 ") without \".set noat\"");
3225 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3226 if (!AssemblerOptions.back()->isMacro())
3227 Warning(Loc, "macro instruction expanded into multiple instructions");
3231 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3232 SMRange Range, bool ShowColors) {
3233 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3234 Range, SMFixIt(Range, FixMsg),
3238 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3241 CC = StringSwitch<unsigned>(Name)
3277 if (!(isABI_N32() || isABI_N64()))
3280 if (12 <= CC && CC <= 15) {
3281 // Name is one of t4-t7
3282 AsmToken RegTok = getLexer().peekTok();
3283 SMRange RegRange = RegTok.getLocRange();
3285 StringRef FixedName = StringSwitch<StringRef>(Name)
3291 assert(FixedName != "" && "Register name is not one of t4-t7.");
3293 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3294 "Did you mean $" + FixedName + "?", RegRange);
3297 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3298 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3299 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3300 if (8 <= CC && CC <= 11)
3304 CC = StringSwitch<unsigned>(Name)
3316 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3319 CC = StringSwitch<unsigned>(Name)
3320 .Case("hwr_cpunum", 0)
3321 .Case("hwr_synci_step", 1)
3323 .Case("hwr_ccres", 3)
3324 .Case("hwr_ulr", 29)
3330 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3332 if (Name[0] == 'f') {
3333 StringRef NumString = Name.substr(1);
3335 if (NumString.getAsInteger(10, IntVal))
3336 return -1; // This is not an integer.
3337 if (IntVal > 31) // Maximum index for fpu register.
3344 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3346 if (Name.startswith("fcc")) {
3347 StringRef NumString = Name.substr(3);
3349 if (NumString.getAsInteger(10, IntVal))
3350 return -1; // This is not an integer.
3351 if (IntVal > 7) // There are only 8 fcc registers.
3358 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3360 if (Name.startswith("ac")) {
3361 StringRef NumString = Name.substr(2);
3363 if (NumString.getAsInteger(10, IntVal))
3364 return -1; // This is not an integer.
3365 if (IntVal > 3) // There are only 3 acc registers.
3372 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3375 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3384 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3387 CC = StringSwitch<unsigned>(Name)
3390 .Case("msaaccess", 2)
3392 .Case("msamodify", 4)
3393 .Case("msarequest", 5)
3395 .Case("msaunmap", 7)
3401 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3402 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3404 reportParseError(Loc,
3405 "pseudo-instruction requires $at, which is not available");
3408 unsigned AT = getReg(
3409 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3413 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3414 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3417 unsigned MipsAsmParser::getGPR(int RegNo) {
3418 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3422 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3424 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3427 return getReg(RegClass, RegNum);
3430 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3431 MCAsmParser &Parser = getParser();
3432 DEBUG(dbgs() << "parseOperand\n");
3434 // Check if the current operand has a custom associated parser, if so, try to
3435 // custom parse the operand, or fallback to the general approach.
3436 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3437 if (ResTy == MatchOperand_Success)
3439 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3440 // there was a match, but an error occurred, in which case, just return that
3441 // the operand parsing failed.
3442 if (ResTy == MatchOperand_ParseFail)
3445 DEBUG(dbgs() << ".. Generic Parser\n");
3447 switch (getLexer().getKind()) {
3449 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3451 case AsmToken::Dollar: {
3452 // Parse the register.
3453 SMLoc S = Parser.getTok().getLoc();
3455 // Almost all registers have been parsed by custom parsers. There is only
3456 // one exception to this. $zero (and it's alias $0) will reach this point
3457 // for div, divu, and similar instructions because it is not an operand
3458 // to the instruction definition but an explicit register. Special case
3459 // this situation for now.
3460 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3463 // Maybe it is a symbol reference.
3464 StringRef Identifier;
3465 if (Parser.parseIdentifier(Identifier))
3468 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3469 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3470 // Otherwise create a symbol reference.
3472 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3474 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3477 // Else drop to expression parsing.
3478 case AsmToken::LParen:
3479 case AsmToken::Minus:
3480 case AsmToken::Plus:
3481 case AsmToken::Integer:
3482 case AsmToken::Tilde:
3483 case AsmToken::String: {
3484 DEBUG(dbgs() << ".. generic integer\n");
3485 OperandMatchResultTy ResTy = parseImm(Operands);
3486 return ResTy != MatchOperand_Success;
3488 case AsmToken::Percent: {
3489 // It is a symbol reference or constant expression.
3490 const MCExpr *IdVal;
3491 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3492 if (parseRelocOperand(IdVal))
3495 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3497 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3499 } // case AsmToken::Percent
3500 } // switch(getLexer().getKind())
3504 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3505 StringRef RelocStr) {
3507 // Check the type of the expression.
3508 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3509 // It's a constant, evaluate reloc value.
3511 switch (getVariantKind(RelocStr)) {
3512 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3513 // Get the 1st 16-bits.
3514 Val = MCE->getValue() & 0xffff;
3516 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3517 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3518 // 16 bits being negative.
3519 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3521 case MCSymbolRefExpr::VK_Mips_HIGHER:
3522 // Get the 3rd 16-bits.
3523 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3525 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3526 // Get the 4th 16-bits.
3527 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3530 report_fatal_error("unsupported reloc value");
3532 return MCConstantExpr::create(Val, getContext());
3535 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3536 // It's a symbol, create a symbolic expression from the symbol.
3537 const MCSymbol *Symbol = &MSRE->getSymbol();
3538 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3539 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3543 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3544 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3546 // Try to create target expression.
3547 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3548 return MipsMCExpr::create(VK, Expr, getContext());
3550 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3551 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3552 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3556 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3557 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3558 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3561 // Just return the original expression.
3565 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3567 switch (Expr->getKind()) {
3568 case MCExpr::Constant:
3570 case MCExpr::SymbolRef:
3571 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3572 case MCExpr::Binary:
3573 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3574 if (!isEvaluated(BE->getLHS()))
3576 return isEvaluated(BE->getRHS());
3579 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3580 case MCExpr::Target:
3586 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3587 MCAsmParser &Parser = getParser();
3588 Parser.Lex(); // Eat the % token.
3589 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3590 if (Tok.isNot(AsmToken::Identifier))
3593 std::string Str = Tok.getIdentifier();
3595 Parser.Lex(); // Eat the identifier.
3596 // Now make an expression from the rest of the operand.
3597 const MCExpr *IdVal;
3600 if (getLexer().getKind() == AsmToken::LParen) {
3602 Parser.Lex(); // Eat the '(' token.
3603 if (getLexer().getKind() == AsmToken::Percent) {
3604 Parser.Lex(); // Eat the % token.
3605 const AsmToken &nextTok = Parser.getTok();
3606 if (nextTok.isNot(AsmToken::Identifier))
3609 Str += nextTok.getIdentifier();
3610 Parser.Lex(); // Eat the identifier.
3611 if (getLexer().getKind() != AsmToken::LParen)
3616 if (getParser().parseParenExpression(IdVal, EndLoc))
3619 while (getLexer().getKind() == AsmToken::RParen)
3620 Parser.Lex(); // Eat the ')' token.
3623 return true; // Parenthesis must follow the relocation operand.
3625 Res = evaluateRelocExpr(IdVal, Str);
3629 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3631 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3632 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3633 if (ResTy == MatchOperand_Success) {
3634 assert(Operands.size() == 1);
3635 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3636 StartLoc = Operand.getStartLoc();
3637 EndLoc = Operand.getEndLoc();
3639 // AFAIK, we only support numeric registers and named GPR's in CFI
3641 // Don't worry about eating tokens before failing. Using an unrecognised
3642 // register is a parse error.
3643 if (Operand.isGPRAsmReg()) {
3644 // Resolve to GPR32 or GPR64 appropriately.
3645 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3648 return (RegNo == (unsigned)-1);
3651 assert(Operands.size() == 0);
3652 return (RegNo == (unsigned)-1);
3655 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3656 MCAsmParser &Parser = getParser();
3659 unsigned NumOfLParen = 0;
3661 while (getLexer().getKind() == AsmToken::LParen) {
3666 switch (getLexer().getKind()) {
3669 case AsmToken::Identifier:
3670 case AsmToken::LParen:
3671 case AsmToken::Integer:
3672 case AsmToken::Minus:
3673 case AsmToken::Plus:
3675 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3677 Result = (getParser().parseExpression(Res));
3678 while (getLexer().getKind() == AsmToken::RParen)
3681 case AsmToken::Percent:
3682 Result = parseRelocOperand(Res);
3687 MipsAsmParser::OperandMatchResultTy
3688 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3689 MCAsmParser &Parser = getParser();
3690 DEBUG(dbgs() << "parseMemOperand\n");
3691 const MCExpr *IdVal = nullptr;
3693 bool isParenExpr = false;
3694 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3695 // First operand is the offset.
3696 S = Parser.getTok().getLoc();
3698 if (getLexer().getKind() == AsmToken::LParen) {
3703 if (getLexer().getKind() != AsmToken::Dollar) {
3704 if (parseMemOffset(IdVal, isParenExpr))
3705 return MatchOperand_ParseFail;
3707 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3708 if (Tok.isNot(AsmToken::LParen)) {
3709 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3710 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3712 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3713 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3714 return MatchOperand_Success;
3716 if (Tok.is(AsmToken::EndOfStatement)) {
3718 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3720 // Zero register assumed, add a memory operand with ZERO as its base.
3721 // "Base" will be managed by k_Memory.
3722 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3725 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3726 return MatchOperand_Success;
3728 Error(Parser.getTok().getLoc(), "'(' expected");
3729 return MatchOperand_ParseFail;
3732 Parser.Lex(); // Eat the '(' token.
3735 Res = parseAnyRegister(Operands);
3736 if (Res != MatchOperand_Success)
3739 if (Parser.getTok().isNot(AsmToken::RParen)) {
3740 Error(Parser.getTok().getLoc(), "')' expected");
3741 return MatchOperand_ParseFail;
3744 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3746 Parser.Lex(); // Eat the ')' token.
3749 IdVal = MCConstantExpr::create(0, getContext());
3751 // Replace the register operand with the memory operand.
3752 std::unique_ptr<MipsOperand> op(
3753 static_cast<MipsOperand *>(Operands.back().release()));
3754 // Remove the register from the operands.
3755 // "op" will be managed by k_Memory.
3756 Operands.pop_back();
3757 // Add the memory operand.
3758 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3760 if (IdVal->evaluateAsAbsolute(Imm))
3761 IdVal = MCConstantExpr::create(Imm, getContext());
3762 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3763 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3767 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3768 return MatchOperand_Success;
3771 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3772 MCAsmParser &Parser = getParser();
3773 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3775 SMLoc S = Parser.getTok().getLoc();
3777 if (Sym->isVariable())
3778 Expr = Sym->getVariableValue();
3781 if (Expr->getKind() == MCExpr::SymbolRef) {
3782 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3783 StringRef DefSymbol = Ref->getSymbol().getName();
3784 if (DefSymbol.startswith("$")) {
3785 OperandMatchResultTy ResTy =
3786 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3787 if (ResTy == MatchOperand_Success) {
3790 } else if (ResTy == MatchOperand_ParseFail)
3791 llvm_unreachable("Should never ParseFail");
3794 } else if (Expr->getKind() == MCExpr::Constant) {
3796 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3798 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3805 MipsAsmParser::OperandMatchResultTy
3806 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3807 StringRef Identifier,
3809 int Index = matchCPURegisterName(Identifier);
3811 Operands.push_back(MipsOperand::createGPRReg(
3812 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3813 return MatchOperand_Success;
3816 Index = matchHWRegsRegisterName(Identifier);
3818 Operands.push_back(MipsOperand::createHWRegsReg(
3819 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3820 return MatchOperand_Success;
3823 Index = matchFPURegisterName(Identifier);
3825 Operands.push_back(MipsOperand::createFGRReg(
3826 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3827 return MatchOperand_Success;
3830 Index = matchFCCRegisterName(Identifier);
3832 Operands.push_back(MipsOperand::createFCCReg(
3833 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3834 return MatchOperand_Success;
3837 Index = matchACRegisterName(Identifier);
3839 Operands.push_back(MipsOperand::createACCReg(
3840 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3841 return MatchOperand_Success;
3844 Index = matchMSA128RegisterName(Identifier);
3846 Operands.push_back(MipsOperand::createMSA128Reg(
3847 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3848 return MatchOperand_Success;
3851 Index = matchMSA128CtrlRegisterName(Identifier);
3853 Operands.push_back(MipsOperand::createMSACtrlReg(
3854 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3855 return MatchOperand_Success;
3858 return MatchOperand_NoMatch;
3861 MipsAsmParser::OperandMatchResultTy
3862 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3863 MCAsmParser &Parser = getParser();
3864 auto Token = Parser.getLexer().peekTok(false);
3866 if (Token.is(AsmToken::Identifier)) {
3867 DEBUG(dbgs() << ".. identifier\n");
3868 StringRef Identifier = Token.getIdentifier();
3869 OperandMatchResultTy ResTy =
3870 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3872 } else if (Token.is(AsmToken::Integer)) {
3873 DEBUG(dbgs() << ".. integer\n");
3874 Operands.push_back(MipsOperand::createNumericReg(
3875 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3877 return MatchOperand_Success;
3880 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3882 return MatchOperand_NoMatch;
3885 MipsAsmParser::OperandMatchResultTy
3886 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3887 MCAsmParser &Parser = getParser();
3888 DEBUG(dbgs() << "parseAnyRegister\n");
3890 auto Token = Parser.getTok();
3892 SMLoc S = Token.getLoc();
3894 if (Token.isNot(AsmToken::Dollar)) {
3895 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3896 if (Token.is(AsmToken::Identifier)) {
3897 if (searchSymbolAlias(Operands))
3898 return MatchOperand_Success;
3900 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3901 return MatchOperand_NoMatch;
3903 DEBUG(dbgs() << ".. $\n");
3905 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3906 if (ResTy == MatchOperand_Success) {
3908 Parser.Lex(); // identifier
3913 MipsAsmParser::OperandMatchResultTy
3914 MipsAsmParser::parseImm(OperandVector &Operands) {
3915 MCAsmParser &Parser = getParser();
3916 switch (getLexer().getKind()) {
3918 return MatchOperand_NoMatch;
3919 case AsmToken::LParen:
3920 case AsmToken::Minus:
3921 case AsmToken::Plus:
3922 case AsmToken::Integer:
3923 case AsmToken::Tilde:
3924 case AsmToken::String:
3928 const MCExpr *IdVal;
3929 SMLoc S = Parser.getTok().getLoc();
3930 if (getParser().parseExpression(IdVal))
3931 return MatchOperand_ParseFail;
3933 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3934 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3935 return MatchOperand_Success;
3938 MipsAsmParser::OperandMatchResultTy
3939 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3940 MCAsmParser &Parser = getParser();
3941 DEBUG(dbgs() << "parseJumpTarget\n");
3943 SMLoc S = getLexer().getLoc();
3945 // Integers and expressions are acceptable
3946 OperandMatchResultTy ResTy = parseImm(Operands);
3947 if (ResTy != MatchOperand_NoMatch)
3950 // Registers are a valid target and have priority over symbols.
3951 ResTy = parseAnyRegister(Operands);
3952 if (ResTy != MatchOperand_NoMatch)
3955 const MCExpr *Expr = nullptr;
3956 if (Parser.parseExpression(Expr)) {
3957 // We have no way of knowing if a symbol was consumed so we must ParseFail
3958 return MatchOperand_ParseFail;
3961 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3962 return MatchOperand_Success;
3965 MipsAsmParser::OperandMatchResultTy
3966 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3967 MCAsmParser &Parser = getParser();
3968 const MCExpr *IdVal;
3969 // If the first token is '$' we may have register operand.
3970 if (Parser.getTok().is(AsmToken::Dollar))
3971 return MatchOperand_NoMatch;
3972 SMLoc S = Parser.getTok().getLoc();
3973 if (getParser().parseExpression(IdVal))
3974 return MatchOperand_ParseFail;
3975 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3976 assert(MCE && "Unexpected MCExpr type.");
3977 int64_t Val = MCE->getValue();
3978 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3979 Operands.push_back(MipsOperand::CreateImm(
3980 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3981 return MatchOperand_Success;
3984 MipsAsmParser::OperandMatchResultTy
3985 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3986 MCAsmParser &Parser = getParser();
3987 switch (getLexer().getKind()) {
3989 return MatchOperand_NoMatch;
3990 case AsmToken::LParen:
3991 case AsmToken::Plus:
3992 case AsmToken::Minus:
3993 case AsmToken::Integer:
3998 SMLoc S = Parser.getTok().getLoc();
4000 if (getParser().parseExpression(Expr))
4001 return MatchOperand_ParseFail;
4004 if (!Expr->evaluateAsAbsolute(Val)) {
4005 Error(S, "expected immediate value");
4006 return MatchOperand_ParseFail;
4009 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4010 // and because the CPU always adds one to the immediate field, the allowed
4011 // range becomes 1..4. We'll only check the range here and will deal
4012 // with the addition/subtraction when actually decoding/encoding
4014 if (Val < 1 || Val > 4) {
4015 Error(S, "immediate not in range (1..4)");
4016 return MatchOperand_ParseFail;
4020 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4021 return MatchOperand_Success;
4024 MipsAsmParser::OperandMatchResultTy
4025 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4026 MCAsmParser &Parser = getParser();
4027 SmallVector<unsigned, 10> Regs;
4029 unsigned PrevReg = Mips::NoRegister;
4030 bool RegRange = false;
4031 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4033 if (Parser.getTok().isNot(AsmToken::Dollar))
4034 return MatchOperand_ParseFail;
4036 SMLoc S = Parser.getTok().getLoc();
4037 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4038 SMLoc E = getLexer().getLoc();
4039 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4040 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4042 // Remove last register operand because registers from register range
4043 // should be inserted first.
4044 if (RegNo == Mips::RA) {
4045 Regs.push_back(RegNo);
4047 unsigned TmpReg = PrevReg + 1;
4048 while (TmpReg <= RegNo) {
4049 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
4050 Error(E, "invalid register operand");
4051 return MatchOperand_ParseFail;
4055 Regs.push_back(TmpReg++);
4061 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
4062 (RegNo != Mips::RA)) {
4063 Error(E, "$16 or $31 expected");
4064 return MatchOperand_ParseFail;
4065 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
4066 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4067 Error(E, "invalid register operand");
4068 return MatchOperand_ParseFail;
4069 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4070 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
4071 Error(E, "consecutive register numbers expected");
4072 return MatchOperand_ParseFail;
4075 Regs.push_back(RegNo);
4078 if (Parser.getTok().is(AsmToken::Minus))
4081 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4082 !Parser.getTok().isNot(AsmToken::Comma)) {
4083 Error(E, "',' or '-' expected");
4084 return MatchOperand_ParseFail;
4087 Lex(); // Consume comma or minus
4088 if (Parser.getTok().isNot(AsmToken::Dollar))
4094 SMLoc E = Parser.getTok().getLoc();
4095 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4096 parseMemOperand(Operands);
4097 return MatchOperand_Success;
4100 MipsAsmParser::OperandMatchResultTy
4101 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4102 MCAsmParser &Parser = getParser();
4104 SMLoc S = Parser.getTok().getLoc();
4105 if (parseAnyRegister(Operands) != MatchOperand_Success)
4106 return MatchOperand_ParseFail;
4108 SMLoc E = Parser.getTok().getLoc();
4109 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4110 unsigned Reg = Op.getGPR32Reg();
4111 Operands.pop_back();
4112 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4113 return MatchOperand_Success;
4116 MipsAsmParser::OperandMatchResultTy
4117 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4118 MCAsmParser &Parser = getParser();
4119 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4120 SmallVector<unsigned, 10> Regs;
4122 if (Parser.getTok().isNot(AsmToken::Dollar))
4123 return MatchOperand_ParseFail;
4125 SMLoc S = Parser.getTok().getLoc();
4127 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4128 return MatchOperand_ParseFail;
4130 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4131 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4132 Regs.push_back(RegNo);
4134 SMLoc E = Parser.getTok().getLoc();
4135 if (Parser.getTok().isNot(AsmToken::Comma)) {
4136 Error(E, "',' expected");
4137 return MatchOperand_ParseFail;
4143 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4144 return MatchOperand_ParseFail;
4146 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4147 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4148 Regs.push_back(RegNo);
4150 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4152 return MatchOperand_Success;
4155 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4157 MCSymbolRefExpr::VariantKind VK =
4158 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4159 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4160 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4161 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4162 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4163 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4164 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4165 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4166 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4167 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4168 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4169 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4170 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4171 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4172 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4173 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4174 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4175 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4176 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4177 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4178 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4179 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4180 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4181 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4182 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4183 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4184 .Default(MCSymbolRefExpr::VK_None);
4186 assert(VK != MCSymbolRefExpr::VK_None);
4191 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4193 /// ::= '(', register, ')'
4194 /// handle it before we iterate so we don't get tripped up by the lack of
4196 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4197 MCAsmParser &Parser = getParser();
4198 if (getLexer().is(AsmToken::LParen)) {
4200 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4202 if (parseOperand(Operands, Name)) {
4203 SMLoc Loc = getLexer().getLoc();
4204 Parser.eatToEndOfStatement();
4205 return Error(Loc, "unexpected token in argument list");
4207 if (Parser.getTok().isNot(AsmToken::RParen)) {
4208 SMLoc Loc = getLexer().getLoc();
4209 Parser.eatToEndOfStatement();
4210 return Error(Loc, "unexpected token, expected ')'");
4213 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4219 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4220 /// either one of these.
4221 /// ::= '[', register, ']'
4222 /// ::= '[', integer, ']'
4223 /// handle it before we iterate so we don't get tripped up by the lack of
4225 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4226 OperandVector &Operands) {
4227 MCAsmParser &Parser = getParser();
4228 if (getLexer().is(AsmToken::LBrac)) {
4230 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4232 if (parseOperand(Operands, Name)) {
4233 SMLoc Loc = getLexer().getLoc();
4234 Parser.eatToEndOfStatement();
4235 return Error(Loc, "unexpected token in argument list");
4237 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4238 SMLoc Loc = getLexer().getLoc();
4239 Parser.eatToEndOfStatement();
4240 return Error(Loc, "unexpected token, expected ']'");
4243 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4249 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4250 SMLoc NameLoc, OperandVector &Operands) {
4251 MCAsmParser &Parser = getParser();
4252 DEBUG(dbgs() << "ParseInstruction\n");
4254 // We have reached first instruction, module directive are now forbidden.
4255 getTargetStreamer().forbidModuleDirective();
4257 // Check if we have valid mnemonic
4258 if (!mnemonicIsValid(Name, 0)) {
4259 Parser.eatToEndOfStatement();
4260 return Error(NameLoc, "unknown instruction");
4262 // First operand in MCInst is instruction mnemonic.
4263 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4265 // Read the remaining operands.
4266 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4267 // Read the first operand.
4268 if (parseOperand(Operands, Name)) {
4269 SMLoc Loc = getLexer().getLoc();
4270 Parser.eatToEndOfStatement();
4271 return Error(Loc, "unexpected token in argument list");
4273 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4275 // AFAIK, parenthesis suffixes are never on the first operand
4277 while (getLexer().is(AsmToken::Comma)) {
4278 Parser.Lex(); // Eat the comma.
4279 // Parse and remember the operand.
4280 if (parseOperand(Operands, Name)) {
4281 SMLoc Loc = getLexer().getLoc();
4282 Parser.eatToEndOfStatement();
4283 return Error(Loc, "unexpected token in argument list");
4285 // Parse bracket and parenthesis suffixes before we iterate
4286 if (getLexer().is(AsmToken::LBrac)) {
4287 if (parseBracketSuffix(Name, Operands))
4289 } else if (getLexer().is(AsmToken::LParen) &&
4290 parseParenSuffix(Name, Operands))
4294 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4295 SMLoc Loc = getLexer().getLoc();
4296 Parser.eatToEndOfStatement();
4297 return Error(Loc, "unexpected token in argument list");
4299 Parser.Lex(); // Consume the EndOfStatement.
4303 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4304 MCAsmParser &Parser = getParser();
4305 SMLoc Loc = getLexer().getLoc();
4306 Parser.eatToEndOfStatement();
4307 return Error(Loc, ErrorMsg);
4310 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4311 return Error(Loc, ErrorMsg);
4314 bool MipsAsmParser::parseSetNoAtDirective() {
4315 MCAsmParser &Parser = getParser();
4316 // Line should look like: ".set noat".
4318 // Set the $at register to $0.
4319 AssemblerOptions.back()->setATRegIndex(0);
4321 Parser.Lex(); // Eat "noat".
4323 // If this is not the end of the statement, report an error.
4324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4325 reportParseError("unexpected token, expected end of statement");
4329 getTargetStreamer().emitDirectiveSetNoAt();
4330 Parser.Lex(); // Consume the EndOfStatement.
4334 bool MipsAsmParser::parseSetAtDirective() {
4335 // Line can be: ".set at", which sets $at to $1
4336 // or ".set at=$reg", which sets $at to $reg.
4337 MCAsmParser &Parser = getParser();
4338 Parser.Lex(); // Eat "at".
4340 if (getLexer().is(AsmToken::EndOfStatement)) {
4341 // No register was specified, so we set $at to $1.
4342 AssemblerOptions.back()->setATRegIndex(1);
4344 getTargetStreamer().emitDirectiveSetAt();
4345 Parser.Lex(); // Consume the EndOfStatement.
4349 if (getLexer().isNot(AsmToken::Equal)) {
4350 reportParseError("unexpected token, expected equals sign");
4353 Parser.Lex(); // Eat "=".
4355 if (getLexer().isNot(AsmToken::Dollar)) {
4356 if (getLexer().is(AsmToken::EndOfStatement)) {
4357 reportParseError("no register specified");
4360 reportParseError("unexpected token, expected dollar sign '$'");
4364 Parser.Lex(); // Eat "$".
4366 // Find out what "reg" is.
4368 const AsmToken &Reg = Parser.getTok();
4369 if (Reg.is(AsmToken::Identifier)) {
4370 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4371 } else if (Reg.is(AsmToken::Integer)) {
4372 AtRegNo = Reg.getIntVal();
4374 reportParseError("unexpected token, expected identifier or integer");
4378 // Check if $reg is a valid register. If it is, set $at to $reg.
4379 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4380 reportParseError("invalid register");
4383 Parser.Lex(); // Eat "reg".
4385 // If this is not the end of the statement, report an error.
4386 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4387 reportParseError("unexpected token, expected end of statement");
4391 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4393 Parser.Lex(); // Consume the EndOfStatement.
4397 bool MipsAsmParser::parseSetReorderDirective() {
4398 MCAsmParser &Parser = getParser();
4400 // If this is not the end of the statement, report an error.
4401 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4402 reportParseError("unexpected token, expected end of statement");
4405 AssemblerOptions.back()->setReorder();
4406 getTargetStreamer().emitDirectiveSetReorder();
4407 Parser.Lex(); // Consume the EndOfStatement.
4411 bool MipsAsmParser::parseSetNoReorderDirective() {
4412 MCAsmParser &Parser = getParser();
4414 // If this is not the end of the statement, report an error.
4415 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4416 reportParseError("unexpected token, expected end of statement");
4419 AssemblerOptions.back()->setNoReorder();
4420 getTargetStreamer().emitDirectiveSetNoReorder();
4421 Parser.Lex(); // Consume the EndOfStatement.
4425 bool MipsAsmParser::parseSetMacroDirective() {
4426 MCAsmParser &Parser = getParser();
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");
4433 AssemblerOptions.back()->setMacro();
4434 getTargetStreamer().emitDirectiveSetMacro();
4435 Parser.Lex(); // Consume the EndOfStatement.
4439 bool MipsAsmParser::parseSetNoMacroDirective() {
4440 MCAsmParser &Parser = getParser();
4442 // If this is not the end of the statement, report an error.
4443 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4444 reportParseError("unexpected token, expected end of statement");
4447 if (AssemblerOptions.back()->isReorder()) {
4448 reportParseError("`noreorder' must be set before `nomacro'");
4451 AssemblerOptions.back()->setNoMacro();
4452 getTargetStreamer().emitDirectiveSetNoMacro();
4453 Parser.Lex(); // Consume the EndOfStatement.
4457 bool MipsAsmParser::parseSetMsaDirective() {
4458 MCAsmParser &Parser = getParser();
4461 // If this is not the end of the statement, report an error.
4462 if (getLexer().isNot(AsmToken::EndOfStatement))
4463 return reportParseError("unexpected token, expected end of statement");
4465 setFeatureBits(Mips::FeatureMSA, "msa");
4466 getTargetStreamer().emitDirectiveSetMsa();
4470 bool MipsAsmParser::parseSetNoMsaDirective() {
4471 MCAsmParser &Parser = getParser();
4474 // If this is not the end of the statement, report an error.
4475 if (getLexer().isNot(AsmToken::EndOfStatement))
4476 return reportParseError("unexpected token, expected end of statement");
4478 clearFeatureBits(Mips::FeatureMSA, "msa");
4479 getTargetStreamer().emitDirectiveSetNoMsa();
4483 bool MipsAsmParser::parseSetNoDspDirective() {
4484 MCAsmParser &Parser = getParser();
4485 Parser.Lex(); // Eat "nodsp".
4487 // If this is not the end of the statement, report an error.
4488 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4489 reportParseError("unexpected token, expected end of statement");
4493 clearFeatureBits(Mips::FeatureDSP, "dsp");
4494 getTargetStreamer().emitDirectiveSetNoDsp();
4498 bool MipsAsmParser::parseSetMips16Directive() {
4499 MCAsmParser &Parser = getParser();
4500 Parser.Lex(); // Eat "mips16".
4502 // If this is not the end of the statement, report an error.
4503 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4504 reportParseError("unexpected token, expected end of statement");
4508 setFeatureBits(Mips::FeatureMips16, "mips16");
4509 getTargetStreamer().emitDirectiveSetMips16();
4510 Parser.Lex(); // Consume the EndOfStatement.
4514 bool MipsAsmParser::parseSetNoMips16Directive() {
4515 MCAsmParser &Parser = getParser();
4516 Parser.Lex(); // Eat "nomips16".
4518 // If this is not the end of the statement, report an error.
4519 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4520 reportParseError("unexpected token, expected end of statement");
4524 clearFeatureBits(Mips::FeatureMips16, "mips16");
4525 getTargetStreamer().emitDirectiveSetNoMips16();
4526 Parser.Lex(); // Consume the EndOfStatement.
4530 bool MipsAsmParser::parseSetFpDirective() {
4531 MCAsmParser &Parser = getParser();
4532 MipsABIFlagsSection::FpABIKind FpAbiVal;
4533 // Line can be: .set fp=32
4536 Parser.Lex(); // Eat fp token
4537 AsmToken Tok = Parser.getTok();
4538 if (Tok.isNot(AsmToken::Equal)) {
4539 reportParseError("unexpected token, expected equals sign '='");
4542 Parser.Lex(); // Eat '=' token.
4543 Tok = Parser.getTok();
4545 if (!parseFpABIValue(FpAbiVal, ".set"))
4548 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4549 reportParseError("unexpected token, expected end of statement");
4552 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4553 Parser.Lex(); // Consume the EndOfStatement.
4557 bool MipsAsmParser::parseSetOddSPRegDirective() {
4558 MCAsmParser &Parser = getParser();
4560 Parser.Lex(); // Eat "oddspreg".
4561 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4562 reportParseError("unexpected token, expected end of statement");
4566 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4567 getTargetStreamer().emitDirectiveSetOddSPReg();
4571 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4572 MCAsmParser &Parser = getParser();
4574 Parser.Lex(); // Eat "nooddspreg".
4575 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4576 reportParseError("unexpected token, expected end of statement");
4580 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4581 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4585 bool MipsAsmParser::parseSetPopDirective() {
4586 MCAsmParser &Parser = getParser();
4587 SMLoc Loc = getLexer().getLoc();
4590 if (getLexer().isNot(AsmToken::EndOfStatement))
4591 return reportParseError("unexpected token, expected end of statement");
4593 // Always keep an element on the options "stack" to prevent the user
4594 // from changing the initial options. This is how we remember them.
4595 if (AssemblerOptions.size() == 2)
4596 return reportParseError(Loc, ".set pop with no .set push");
4598 AssemblerOptions.pop_back();
4599 setAvailableFeatures(
4600 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4601 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4603 getTargetStreamer().emitDirectiveSetPop();
4607 bool MipsAsmParser::parseSetPushDirective() {
4608 MCAsmParser &Parser = getParser();
4610 if (getLexer().isNot(AsmToken::EndOfStatement))
4611 return reportParseError("unexpected token, expected end of statement");
4613 // Create a copy of the current assembler options environment and push it.
4614 AssemblerOptions.push_back(
4615 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4617 getTargetStreamer().emitDirectiveSetPush();
4621 bool MipsAsmParser::parseSetSoftFloatDirective() {
4622 MCAsmParser &Parser = getParser();
4624 if (getLexer().isNot(AsmToken::EndOfStatement))
4625 return reportParseError("unexpected token, expected end of statement");
4627 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4628 getTargetStreamer().emitDirectiveSetSoftFloat();
4632 bool MipsAsmParser::parseSetHardFloatDirective() {
4633 MCAsmParser &Parser = getParser();
4635 if (getLexer().isNot(AsmToken::EndOfStatement))
4636 return reportParseError("unexpected token, expected end of statement");
4638 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4639 getTargetStreamer().emitDirectiveSetHardFloat();
4643 bool MipsAsmParser::parseSetAssignment() {
4645 const MCExpr *Value;
4646 MCAsmParser &Parser = getParser();
4648 if (Parser.parseIdentifier(Name))
4649 reportParseError("expected identifier after .set");
4651 if (getLexer().isNot(AsmToken::Comma))
4652 return reportParseError("unexpected token, expected comma");
4655 if (Parser.parseExpression(Value))
4656 return reportParseError("expected valid expression after comma");
4658 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4659 Sym->setVariableValue(Value);
4664 bool MipsAsmParser::parseSetMips0Directive() {
4665 MCAsmParser &Parser = getParser();
4667 if (getLexer().isNot(AsmToken::EndOfStatement))
4668 return reportParseError("unexpected token, expected end of statement");
4670 // Reset assembler options to their initial values.
4671 setAvailableFeatures(
4672 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4673 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4674 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4676 getTargetStreamer().emitDirectiveSetMips0();
4680 bool MipsAsmParser::parseSetArchDirective() {
4681 MCAsmParser &Parser = getParser();
4683 if (getLexer().isNot(AsmToken::Equal))
4684 return reportParseError("unexpected token, expected equals sign");
4688 if (Parser.parseIdentifier(Arch))
4689 return reportParseError("expected arch identifier");
4691 StringRef ArchFeatureName =
4692 StringSwitch<StringRef>(Arch)
4693 .Case("mips1", "mips1")
4694 .Case("mips2", "mips2")
4695 .Case("mips3", "mips3")
4696 .Case("mips4", "mips4")
4697 .Case("mips5", "mips5")
4698 .Case("mips32", "mips32")
4699 .Case("mips32r2", "mips32r2")
4700 .Case("mips32r3", "mips32r3")
4701 .Case("mips32r5", "mips32r5")
4702 .Case("mips32r6", "mips32r6")
4703 .Case("mips64", "mips64")
4704 .Case("mips64r2", "mips64r2")
4705 .Case("mips64r3", "mips64r3")
4706 .Case("mips64r5", "mips64r5")
4707 .Case("mips64r6", "mips64r6")
4708 .Case("cnmips", "cnmips")
4709 .Case("r4000", "mips3") // This is an implementation of Mips3.
4712 if (ArchFeatureName.empty())
4713 return reportParseError("unsupported architecture");
4715 selectArch(ArchFeatureName);
4716 getTargetStreamer().emitDirectiveSetArch(Arch);
4720 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4721 MCAsmParser &Parser = getParser();
4723 if (getLexer().isNot(AsmToken::EndOfStatement))
4724 return reportParseError("unexpected token, expected end of statement");
4728 llvm_unreachable("Unimplemented feature");
4729 case Mips::FeatureDSP:
4730 setFeatureBits(Mips::FeatureDSP, "dsp");
4731 getTargetStreamer().emitDirectiveSetDsp();
4733 case Mips::FeatureMicroMips:
4734 getTargetStreamer().emitDirectiveSetMicroMips();
4736 case Mips::FeatureMips1:
4737 selectArch("mips1");
4738 getTargetStreamer().emitDirectiveSetMips1();
4740 case Mips::FeatureMips2:
4741 selectArch("mips2");
4742 getTargetStreamer().emitDirectiveSetMips2();
4744 case Mips::FeatureMips3:
4745 selectArch("mips3");
4746 getTargetStreamer().emitDirectiveSetMips3();
4748 case Mips::FeatureMips4:
4749 selectArch("mips4");
4750 getTargetStreamer().emitDirectiveSetMips4();
4752 case Mips::FeatureMips5:
4753 selectArch("mips5");
4754 getTargetStreamer().emitDirectiveSetMips5();
4756 case Mips::FeatureMips32:
4757 selectArch("mips32");
4758 getTargetStreamer().emitDirectiveSetMips32();
4760 case Mips::FeatureMips32r2:
4761 selectArch("mips32r2");
4762 getTargetStreamer().emitDirectiveSetMips32R2();
4764 case Mips::FeatureMips32r3:
4765 selectArch("mips32r3");
4766 getTargetStreamer().emitDirectiveSetMips32R3();
4768 case Mips::FeatureMips32r5:
4769 selectArch("mips32r5");
4770 getTargetStreamer().emitDirectiveSetMips32R5();
4772 case Mips::FeatureMips32r6:
4773 selectArch("mips32r6");
4774 getTargetStreamer().emitDirectiveSetMips32R6();
4776 case Mips::FeatureMips64:
4777 selectArch("mips64");
4778 getTargetStreamer().emitDirectiveSetMips64();
4780 case Mips::FeatureMips64r2:
4781 selectArch("mips64r2");
4782 getTargetStreamer().emitDirectiveSetMips64R2();
4784 case Mips::FeatureMips64r3:
4785 selectArch("mips64r3");
4786 getTargetStreamer().emitDirectiveSetMips64R3();
4788 case Mips::FeatureMips64r5:
4789 selectArch("mips64r5");
4790 getTargetStreamer().emitDirectiveSetMips64R5();
4792 case Mips::FeatureMips64r6:
4793 selectArch("mips64r6");
4794 getTargetStreamer().emitDirectiveSetMips64R6();
4800 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4801 MCAsmParser &Parser = getParser();
4802 if (getLexer().isNot(AsmToken::Comma)) {
4803 SMLoc Loc = getLexer().getLoc();
4804 Parser.eatToEndOfStatement();
4805 return Error(Loc, ErrorStr);
4808 Parser.Lex(); // Eat the comma.
4812 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4813 // In this class, it is only used for .cprestore.
4814 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4815 // MipsTargetELFStreamer and MipsAsmParser.
4816 bool MipsAsmParser::isPicAndNotNxxAbi() {
4817 return inPicMode() && !(isABI_N32() || isABI_N64());
4820 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4821 if (AssemblerOptions.back()->isReorder())
4822 Warning(Loc, ".cpload should be inside a noreorder section");
4824 if (inMips16Mode()) {
4825 reportParseError(".cpload is not supported in Mips16 mode");
4829 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4830 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4831 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4832 reportParseError("expected register containing function address");
4836 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4837 if (!RegOpnd.isGPRAsmReg()) {
4838 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4842 // If this is not the end of the statement, report an error.
4843 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4844 reportParseError("unexpected token, expected end of statement");
4848 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4852 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
4853 MCAsmParser &Parser = getParser();
4855 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
4856 // is used in non-PIC mode.
4858 if (inMips16Mode()) {
4859 reportParseError(".cprestore is not supported in Mips16 mode");
4863 // Get the stack offset value.
4864 const MCExpr *StackOffset;
4865 int64_t StackOffsetVal;
4866 if (Parser.parseExpression(StackOffset)) {
4867 reportParseError("expected stack offset value");
4871 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
4872 reportParseError("stack offset is not an absolute expression");
4876 if (StackOffsetVal < 0) {
4877 Warning(Loc, ".cprestore with negative stack offset has no effect");
4878 IsCpRestoreSet = false;
4880 IsCpRestoreSet = true;
4881 CpRestoreOffset = StackOffsetVal;
4884 // If this is not the end of the statement, report an error.
4885 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4886 reportParseError("unexpected token, expected end of statement");
4890 // Store the $gp on the stack.
4891 SmallVector<MCInst, 3> StoreInsts;
4892 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
4895 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
4896 Parser.Lex(); // Consume the EndOfStatement.
4900 bool MipsAsmParser::parseDirectiveCPSetup() {
4901 MCAsmParser &Parser = getParser();
4904 bool SaveIsReg = true;
4906 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4907 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4908 if (ResTy == MatchOperand_NoMatch) {
4909 reportParseError("expected register containing function address");
4910 Parser.eatToEndOfStatement();
4914 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4915 if (!FuncRegOpnd.isGPRAsmReg()) {
4916 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4917 Parser.eatToEndOfStatement();
4921 FuncReg = FuncRegOpnd.getGPR32Reg();
4924 if (!eatComma("unexpected token, expected comma"))
4927 ResTy = parseAnyRegister(TmpReg);
4928 if (ResTy == MatchOperand_NoMatch) {
4929 const MCExpr *OffsetExpr;
4931 SMLoc ExprLoc = getLexer().getLoc();
4933 if (Parser.parseExpression(OffsetExpr) ||
4934 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
4935 reportParseError(ExprLoc, "expected save register or stack offset");
4936 Parser.eatToEndOfStatement();
4943 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4944 if (!SaveOpnd.isGPRAsmReg()) {
4945 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4946 Parser.eatToEndOfStatement();
4949 Save = SaveOpnd.getGPR32Reg();
4952 if (!eatComma("unexpected token, expected comma"))
4956 if (Parser.parseExpression(Expr)) {
4957 reportParseError("expected expression");
4961 if (Expr->getKind() != MCExpr::SymbolRef) {
4962 reportParseError("expected symbol");
4965 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4967 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4972 bool MipsAsmParser::parseDirectiveNaN() {
4973 MCAsmParser &Parser = getParser();
4974 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4975 const AsmToken &Tok = Parser.getTok();
4977 if (Tok.getString() == "2008") {
4979 getTargetStreamer().emitDirectiveNaN2008();
4981 } else if (Tok.getString() == "legacy") {
4983 getTargetStreamer().emitDirectiveNaNLegacy();
4987 // If we don't recognize the option passed to the .nan
4988 // directive (e.g. no option or unknown option), emit an error.
4989 reportParseError("invalid option in .nan directive");
4993 bool MipsAsmParser::parseDirectiveSet() {
4994 MCAsmParser &Parser = getParser();
4995 // Get the next token.
4996 const AsmToken &Tok = Parser.getTok();
4998 if (Tok.getString() == "noat") {
4999 return parseSetNoAtDirective();
5000 } else if (Tok.getString() == "at") {
5001 return parseSetAtDirective();
5002 } else if (Tok.getString() == "arch") {
5003 return parseSetArchDirective();
5004 } else if (Tok.getString() == "fp") {
5005 return parseSetFpDirective();
5006 } else if (Tok.getString() == "oddspreg") {
5007 return parseSetOddSPRegDirective();
5008 } else if (Tok.getString() == "nooddspreg") {
5009 return parseSetNoOddSPRegDirective();
5010 } else if (Tok.getString() == "pop") {
5011 return parseSetPopDirective();
5012 } else if (Tok.getString() == "push") {
5013 return parseSetPushDirective();
5014 } else if (Tok.getString() == "reorder") {
5015 return parseSetReorderDirective();
5016 } else if (Tok.getString() == "noreorder") {
5017 return parseSetNoReorderDirective();
5018 } else if (Tok.getString() == "macro") {
5019 return parseSetMacroDirective();
5020 } else if (Tok.getString() == "nomacro") {
5021 return parseSetNoMacroDirective();
5022 } else if (Tok.getString() == "mips16") {
5023 return parseSetMips16Directive();
5024 } else if (Tok.getString() == "nomips16") {
5025 return parseSetNoMips16Directive();
5026 } else if (Tok.getString() == "nomicromips") {
5027 getTargetStreamer().emitDirectiveSetNoMicroMips();
5028 Parser.eatToEndOfStatement();
5030 } else if (Tok.getString() == "micromips") {
5031 return parseSetFeature(Mips::FeatureMicroMips);
5032 } else if (Tok.getString() == "mips0") {
5033 return parseSetMips0Directive();
5034 } else if (Tok.getString() == "mips1") {
5035 return parseSetFeature(Mips::FeatureMips1);
5036 } else if (Tok.getString() == "mips2") {
5037 return parseSetFeature(Mips::FeatureMips2);
5038 } else if (Tok.getString() == "mips3") {
5039 return parseSetFeature(Mips::FeatureMips3);
5040 } else if (Tok.getString() == "mips4") {
5041 return parseSetFeature(Mips::FeatureMips4);
5042 } else if (Tok.getString() == "mips5") {
5043 return parseSetFeature(Mips::FeatureMips5);
5044 } else if (Tok.getString() == "mips32") {
5045 return parseSetFeature(Mips::FeatureMips32);
5046 } else if (Tok.getString() == "mips32r2") {
5047 return parseSetFeature(Mips::FeatureMips32r2);
5048 } else if (Tok.getString() == "mips32r3") {
5049 return parseSetFeature(Mips::FeatureMips32r3);
5050 } else if (Tok.getString() == "mips32r5") {
5051 return parseSetFeature(Mips::FeatureMips32r5);
5052 } else if (Tok.getString() == "mips32r6") {
5053 return parseSetFeature(Mips::FeatureMips32r6);
5054 } else if (Tok.getString() == "mips64") {
5055 return parseSetFeature(Mips::FeatureMips64);
5056 } else if (Tok.getString() == "mips64r2") {
5057 return parseSetFeature(Mips::FeatureMips64r2);
5058 } else if (Tok.getString() == "mips64r3") {
5059 return parseSetFeature(Mips::FeatureMips64r3);
5060 } else if (Tok.getString() == "mips64r5") {
5061 return parseSetFeature(Mips::FeatureMips64r5);
5062 } else if (Tok.getString() == "mips64r6") {
5063 return parseSetFeature(Mips::FeatureMips64r6);
5064 } else if (Tok.getString() == "dsp") {
5065 return parseSetFeature(Mips::FeatureDSP);
5066 } else if (Tok.getString() == "nodsp") {
5067 return parseSetNoDspDirective();
5068 } else if (Tok.getString() == "msa") {
5069 return parseSetMsaDirective();
5070 } else if (Tok.getString() == "nomsa") {
5071 return parseSetNoMsaDirective();
5072 } else if (Tok.getString() == "softfloat") {
5073 return parseSetSoftFloatDirective();
5074 } else if (Tok.getString() == "hardfloat") {
5075 return parseSetHardFloatDirective();
5077 // It is just an identifier, look for an assignment.
5078 parseSetAssignment();
5085 /// parseDataDirective
5086 /// ::= .word [ expression (, expression)* ]
5087 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5088 MCAsmParser &Parser = getParser();
5089 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5091 const MCExpr *Value;
5092 if (getParser().parseExpression(Value))
5095 getParser().getStreamer().EmitValue(Value, Size);
5097 if (getLexer().is(AsmToken::EndOfStatement))
5100 if (getLexer().isNot(AsmToken::Comma))
5101 return Error(L, "unexpected token, expected comma");
5110 /// parseDirectiveGpWord
5111 /// ::= .gpword local_sym
5112 bool MipsAsmParser::parseDirectiveGpWord() {
5113 MCAsmParser &Parser = getParser();
5114 const MCExpr *Value;
5115 // EmitGPRel32Value requires an expression, so we are using base class
5116 // method to evaluate the expression.
5117 if (getParser().parseExpression(Value))
5119 getParser().getStreamer().EmitGPRel32Value(Value);
5121 if (getLexer().isNot(AsmToken::EndOfStatement))
5122 return Error(getLexer().getLoc(),
5123 "unexpected token, expected end of statement");
5124 Parser.Lex(); // Eat EndOfStatement token.
5128 /// parseDirectiveGpDWord
5129 /// ::= .gpdword local_sym
5130 bool MipsAsmParser::parseDirectiveGpDWord() {
5131 MCAsmParser &Parser = getParser();
5132 const MCExpr *Value;
5133 // EmitGPRel64Value requires an expression, so we are using base class
5134 // method to evaluate the expression.
5135 if (getParser().parseExpression(Value))
5137 getParser().getStreamer().EmitGPRel64Value(Value);
5139 if (getLexer().isNot(AsmToken::EndOfStatement))
5140 return Error(getLexer().getLoc(),
5141 "unexpected token, expected end of statement");
5142 Parser.Lex(); // Eat EndOfStatement token.
5146 bool MipsAsmParser::parseDirectiveOption() {
5147 MCAsmParser &Parser = getParser();
5148 // Get the option token.
5149 AsmToken Tok = Parser.getTok();
5150 // At the moment only identifiers are supported.
5151 if (Tok.isNot(AsmToken::Identifier)) {
5152 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5153 Parser.eatToEndOfStatement();
5157 StringRef Option = Tok.getIdentifier();
5159 if (Option == "pic0") {
5160 // MipsAsmParser needs to know if the current PIC mode changes.
5161 IsPicEnabled = false;
5163 getTargetStreamer().emitDirectiveOptionPic0();
5165 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5166 Error(Parser.getTok().getLoc(),
5167 "unexpected token, expected end of statement");
5168 Parser.eatToEndOfStatement();
5173 if (Option == "pic2") {
5174 // MipsAsmParser needs to know if the current PIC mode changes.
5175 IsPicEnabled = true;
5177 getTargetStreamer().emitDirectiveOptionPic2();
5179 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5180 Error(Parser.getTok().getLoc(),
5181 "unexpected token, expected end of statement");
5182 Parser.eatToEndOfStatement();
5188 Warning(Parser.getTok().getLoc(),
5189 "unknown option, expected 'pic0' or 'pic2'");
5190 Parser.eatToEndOfStatement();
5194 /// parseInsnDirective
5196 bool MipsAsmParser::parseInsnDirective() {
5197 // If this is not the end of the statement, report an error.
5198 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5199 reportParseError("unexpected token, expected end of statement");
5203 // The actual label marking happens in
5204 // MipsELFStreamer::createPendingLabelRelocs().
5205 getTargetStreamer().emitDirectiveInsn();
5207 getParser().Lex(); // Eat EndOfStatement token.
5211 /// parseDirectiveModule
5212 /// ::= .module oddspreg
5213 /// ::= .module nooddspreg
5214 /// ::= .module fp=value
5215 /// ::= .module softfloat
5216 /// ::= .module hardfloat
5217 bool MipsAsmParser::parseDirectiveModule() {
5218 MCAsmParser &Parser = getParser();
5219 MCAsmLexer &Lexer = getLexer();
5220 SMLoc L = Lexer.getLoc();
5222 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5223 // TODO : get a better message.
5224 reportParseError(".module directive must appear before any code");
5229 if (Parser.parseIdentifier(Option)) {
5230 reportParseError("expected .module option identifier");
5234 if (Option == "oddspreg") {
5235 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5237 // Synchronize the abiflags information with the FeatureBits information we
5239 getTargetStreamer().updateABIInfo(*this);
5241 // If printing assembly, use the recently updated abiflags information.
5242 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5243 // emitted at the end).
5244 getTargetStreamer().emitDirectiveModuleOddSPReg();
5246 // If this is not the end of the statement, report an error.
5247 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5248 reportParseError("unexpected token, expected end of statement");
5252 return false; // parseDirectiveModule has finished successfully.
5253 } else if (Option == "nooddspreg") {
5255 Error(L, "'.module nooddspreg' requires the O32 ABI");
5259 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5261 // Synchronize the abiflags information with the FeatureBits information we
5263 getTargetStreamer().updateABIInfo(*this);
5265 // If printing assembly, use the recently updated abiflags information.
5266 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5267 // emitted at the end).
5268 getTargetStreamer().emitDirectiveModuleOddSPReg();
5270 // If this is not the end of the statement, report an error.
5271 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5272 reportParseError("unexpected token, expected end of statement");
5276 return false; // parseDirectiveModule has finished successfully.
5277 } else if (Option == "fp") {
5278 return parseDirectiveModuleFP();
5279 } else if (Option == "softfloat") {
5280 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5282 // Synchronize the ABI Flags information with the FeatureBits information we
5284 getTargetStreamer().updateABIInfo(*this);
5286 // If printing assembly, use the recently updated ABI Flags information.
5287 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5289 getTargetStreamer().emitDirectiveModuleSoftFloat();
5291 // If this is not the end of the statement, report an error.
5292 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5293 reportParseError("unexpected token, expected end of statement");
5297 return false; // parseDirectiveModule has finished successfully.
5298 } else if (Option == "hardfloat") {
5299 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5301 // Synchronize the ABI Flags information with the FeatureBits information we
5303 getTargetStreamer().updateABIInfo(*this);
5305 // If printing assembly, use the recently updated ABI Flags information.
5306 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5308 getTargetStreamer().emitDirectiveModuleHardFloat();
5310 // If this is not the end of the statement, report an error.
5311 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5312 reportParseError("unexpected token, expected end of statement");
5316 return false; // parseDirectiveModule has finished successfully.
5318 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5322 /// parseDirectiveModuleFP
5326 bool MipsAsmParser::parseDirectiveModuleFP() {
5327 MCAsmParser &Parser = getParser();
5328 MCAsmLexer &Lexer = getLexer();
5330 if (Lexer.isNot(AsmToken::Equal)) {
5331 reportParseError("unexpected token, expected equals sign '='");
5334 Parser.Lex(); // Eat '=' token.
5336 MipsABIFlagsSection::FpABIKind FpABI;
5337 if (!parseFpABIValue(FpABI, ".module"))
5340 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5341 reportParseError("unexpected token, expected end of statement");
5345 // Synchronize the abiflags information with the FeatureBits information we
5347 getTargetStreamer().updateABIInfo(*this);
5349 // If printing assembly, use the recently updated abiflags information.
5350 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5351 // emitted at the end).
5352 getTargetStreamer().emitDirectiveModuleFP();
5354 Parser.Lex(); // Consume the EndOfStatement.
5358 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5359 StringRef Directive) {
5360 MCAsmParser &Parser = getParser();
5361 MCAsmLexer &Lexer = getLexer();
5362 bool ModuleLevelOptions = Directive == ".module";
5364 if (Lexer.is(AsmToken::Identifier)) {
5365 StringRef Value = Parser.getTok().getString();
5368 if (Value != "xx") {
5369 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5374 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5378 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5379 if (ModuleLevelOptions) {
5380 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5381 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5383 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5384 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5389 if (Lexer.is(AsmToken::Integer)) {
5390 unsigned Value = Parser.getTok().getIntVal();
5393 if (Value != 32 && Value != 64) {
5394 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5400 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5404 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5405 if (ModuleLevelOptions) {
5406 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5407 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5409 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5410 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5413 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5414 if (ModuleLevelOptions) {
5415 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5416 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5418 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5419 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5429 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5430 MCAsmParser &Parser = getParser();
5431 StringRef IDVal = DirectiveID.getString();
5433 if (IDVal == ".cpload")
5434 return parseDirectiveCpLoad(DirectiveID.getLoc());
5435 if (IDVal == ".cprestore")
5436 return parseDirectiveCpRestore(DirectiveID.getLoc());
5437 if (IDVal == ".dword") {
5438 parseDataDirective(8, DirectiveID.getLoc());
5441 if (IDVal == ".ent") {
5442 StringRef SymbolName;
5444 if (Parser.parseIdentifier(SymbolName)) {
5445 reportParseError("expected identifier after .ent");
5449 // There's an undocumented extension that allows an integer to
5450 // follow the name of the procedure which AFAICS is ignored by GAS.
5451 // Example: .ent foo,2
5452 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5453 if (getLexer().isNot(AsmToken::Comma)) {
5454 // Even though we accept this undocumented extension for compatibility
5455 // reasons, the additional integer argument does not actually change
5456 // the behaviour of the '.ent' directive, so we would like to discourage
5457 // its use. We do this by not referring to the extended version in
5458 // error messages which are not directly related to its use.
5459 reportParseError("unexpected token, expected end of statement");
5462 Parser.Lex(); // Eat the comma.
5463 const MCExpr *DummyNumber;
5464 int64_t DummyNumberVal;
5465 // If the user was explicitly trying to use the extended version,
5466 // we still give helpful extension-related error messages.
5467 if (Parser.parseExpression(DummyNumber)) {
5468 reportParseError("expected number after comma");
5471 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5472 reportParseError("expected an absolute expression after comma");
5477 // If this is not the end of the statement, report an error.
5478 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5479 reportParseError("unexpected token, expected end of statement");
5483 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5485 getTargetStreamer().emitDirectiveEnt(*Sym);
5487 IsCpRestoreSet = false;
5491 if (IDVal == ".end") {
5492 StringRef SymbolName;
5494 if (Parser.parseIdentifier(SymbolName)) {
5495 reportParseError("expected identifier after .end");
5499 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5500 reportParseError("unexpected token, expected end of statement");
5504 if (CurrentFn == nullptr) {
5505 reportParseError(".end used without .ent");
5509 if ((SymbolName != CurrentFn->getName())) {
5510 reportParseError(".end symbol does not match .ent symbol");
5514 getTargetStreamer().emitDirectiveEnd(SymbolName);
5515 CurrentFn = nullptr;
5516 IsCpRestoreSet = false;
5520 if (IDVal == ".frame") {
5521 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5522 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5523 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5524 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5525 reportParseError("expected stack register");
5529 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5530 if (!StackRegOpnd.isGPRAsmReg()) {
5531 reportParseError(StackRegOpnd.getStartLoc(),
5532 "expected general purpose register");
5535 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5537 if (Parser.getTok().is(AsmToken::Comma))
5540 reportParseError("unexpected token, expected comma");
5544 // Parse the frame size.
5545 const MCExpr *FrameSize;
5546 int64_t FrameSizeVal;
5548 if (Parser.parseExpression(FrameSize)) {
5549 reportParseError("expected frame size value");
5553 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5554 reportParseError("frame size not an absolute expression");
5558 if (Parser.getTok().is(AsmToken::Comma))
5561 reportParseError("unexpected token, expected comma");
5565 // Parse the return register.
5567 ResTy = parseAnyRegister(TmpReg);
5568 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5569 reportParseError("expected return register");
5573 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5574 if (!ReturnRegOpnd.isGPRAsmReg()) {
5575 reportParseError(ReturnRegOpnd.getStartLoc(),
5576 "expected general purpose register");
5580 // If this is not the end of the statement, report an error.
5581 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5582 reportParseError("unexpected token, expected end of statement");
5586 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5587 ReturnRegOpnd.getGPR32Reg());
5588 IsCpRestoreSet = false;
5592 if (IDVal == ".set") {
5593 return parseDirectiveSet();
5596 if (IDVal == ".mask" || IDVal == ".fmask") {
5597 // .mask bitmask, frame_offset
5598 // bitmask: One bit for each register used.
5599 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5600 // first register is expected to be saved.
5602 // .mask 0x80000000, -4
5603 // .fmask 0x80000000, -4
5606 // Parse the bitmask
5607 const MCExpr *BitMask;
5610 if (Parser.parseExpression(BitMask)) {
5611 reportParseError("expected bitmask value");
5615 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5616 reportParseError("bitmask not an absolute expression");
5620 if (Parser.getTok().is(AsmToken::Comma))
5623 reportParseError("unexpected token, expected comma");
5627 // Parse the frame_offset
5628 const MCExpr *FrameOffset;
5629 int64_t FrameOffsetVal;
5631 if (Parser.parseExpression(FrameOffset)) {
5632 reportParseError("expected frame offset value");
5636 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5637 reportParseError("frame offset not an absolute expression");
5641 // If this is not the end of the statement, report an error.
5642 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5643 reportParseError("unexpected token, expected end of statement");
5647 if (IDVal == ".mask")
5648 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5650 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5654 if (IDVal == ".nan")
5655 return parseDirectiveNaN();
5657 if (IDVal == ".gpword") {
5658 parseDirectiveGpWord();
5662 if (IDVal == ".gpdword") {
5663 parseDirectiveGpDWord();
5667 if (IDVal == ".word") {
5668 parseDataDirective(4, DirectiveID.getLoc());
5672 if (IDVal == ".option")
5673 return parseDirectiveOption();
5675 if (IDVal == ".abicalls") {
5676 getTargetStreamer().emitDirectiveAbiCalls();
5677 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5678 Error(Parser.getTok().getLoc(),
5679 "unexpected token, expected end of statement");
5681 Parser.eatToEndOfStatement();
5686 if (IDVal == ".cpsetup")
5687 return parseDirectiveCPSetup();
5689 if (IDVal == ".module")
5690 return parseDirectiveModule();
5692 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5693 return parseInternalDirectiveReallowModule();
5695 if (IDVal == ".insn")
5696 return parseInsnDirective();
5701 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5702 // If this is not the end of the statement, report an error.
5703 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5704 reportParseError("unexpected token, expected end of statement");
5708 getTargetStreamer().reallowModuleDirective();
5710 getParser().Lex(); // Eat EndOfStatement token.
5714 extern "C" void LLVMInitializeMipsAsmParser() {
5715 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5716 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5717 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5718 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5721 #define GET_REGISTER_MATCHER
5722 #define GET_MATCHER_IMPLEMENTATION
5723 #include "MipsGenAsmMatcher.inc"