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 "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(const FeatureBitset &Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegIndex();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegIndex() const { return ATReg; }
57 bool setATRegIndex(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 const FeatureBitset &getFeatures() const { return Features; }
74 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const FeatureBitset AllArchRelatedMask;
87 FeatureBitset Features;
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103 class MipsAsmParser : public MCTargetAsmParser {
104 MipsTargetStreamer &getTargetStreamer() {
105 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
106 return static_cast<MipsTargetStreamer &>(TS);
109 MCSubtargetInfo &STI;
111 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
112 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113 // nullptr, which indicates that no function is currently
114 // selected. This usually happens after an '.end func'
118 // Print a warning along with its fix-it message at the given range.
119 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
120 SMRange Range, bool ShowColors = true);
122 #define GET_ASSEMBLER_HEADER
123 #include "MipsGenAsmMatcher.inc"
125 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
127 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
128 OperandVector &Operands, MCStreamer &Out,
130 bool MatchingInlineAsm) override;
132 /// Parse a register as used in CFI directives
133 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
135 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
137 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
139 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
140 SMLoc NameLoc, OperandVector &Operands) override;
142 bool ParseDirective(AsmToken DirectiveID) override;
144 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
146 MipsAsmParser::OperandMatchResultTy
147 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
148 StringRef Identifier, SMLoc S);
150 MipsAsmParser::OperandMatchResultTy
151 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
153 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
161 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
163 MipsAsmParser::OperandMatchResultTy
164 parseRegisterPair (OperandVector &Operands);
166 MipsAsmParser::OperandMatchResultTy
167 parseMovePRegPair(OperandVector &Operands);
169 MipsAsmParser::OperandMatchResultTy
170 parseRegisterList (OperandVector &Operands);
172 bool searchSymbolAlias(OperandVector &Operands);
174 bool parseOperand(OperandVector &, StringRef Mnemonic);
176 bool needsExpansion(MCInst &Inst);
178 // Expands assembly pseudo instructions.
179 // Returns false on success, true otherwise.
180 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
183 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
186 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
187 bool Is32BitImm, SMLoc IDLoc,
188 SmallVectorImpl<MCInst> &Instructions);
190 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
191 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
192 SmallVectorImpl<MCInst> &Instructions);
194 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
195 SmallVectorImpl<MCInst> &Instructions);
197 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
202 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions);
205 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
209 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
210 SmallVectorImpl<MCInst> &Instructions);
212 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
213 SmallVectorImpl<MCInst> &Instructions);
215 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
216 SmallVectorImpl<MCInst> &Instructions);
218 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions);
221 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
222 SmallVectorImpl<MCInst> &Instructions);
224 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
225 SmallVectorImpl<MCInst> &Instructions);
227 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
228 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
230 bool reportParseError(Twine ErrorMsg);
231 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
233 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
234 bool parseRelocOperand(const MCExpr *&Res);
236 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
238 bool isEvaluated(const MCExpr *Expr);
239 bool parseSetMips0Directive();
240 bool parseSetArchDirective();
241 bool parseSetFeature(uint64_t Feature);
242 bool parseDirectiveCpLoad(SMLoc Loc);
243 bool parseDirectiveCPSetup();
244 bool parseDirectiveNaN();
245 bool parseDirectiveSet();
246 bool parseDirectiveOption();
247 bool parseInsnDirective();
249 bool parseSetAtDirective();
250 bool parseSetNoAtDirective();
251 bool parseSetMacroDirective();
252 bool parseSetNoMacroDirective();
253 bool parseSetMsaDirective();
254 bool parseSetNoMsaDirective();
255 bool parseSetNoDspDirective();
256 bool parseSetReorderDirective();
257 bool parseSetNoReorderDirective();
258 bool parseSetMips16Directive();
259 bool parseSetNoMips16Directive();
260 bool parseSetFpDirective();
261 bool parseSetOddSPRegDirective();
262 bool parseSetNoOddSPRegDirective();
263 bool parseSetPopDirective();
264 bool parseSetPushDirective();
265 bool parseSetSoftFloatDirective();
266 bool parseSetHardFloatDirective();
268 bool parseSetAssignment();
270 bool parseDataDirective(unsigned Size, SMLoc L);
271 bool parseDirectiveGpWord();
272 bool parseDirectiveGpDWord();
273 bool parseDirectiveModule();
274 bool parseDirectiveModuleFP();
275 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
276 StringRef Directive);
278 bool parseInternalDirectiveReallowModule();
280 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
282 bool eatComma(StringRef ErrorStr);
284 int matchCPURegisterName(StringRef Symbol);
286 int matchHWRegsRegisterName(StringRef Symbol);
288 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
290 int matchFPURegisterName(StringRef Name);
292 int matchFCCRegisterName(StringRef Name);
294 int matchACRegisterName(StringRef Name);
296 int matchMSA128RegisterName(StringRef Name);
298 int matchMSA128CtrlRegisterName(StringRef Name);
300 unsigned getReg(int RC, int RegNo);
302 unsigned getGPR(int RegNo);
304 /// Returns the internal register number for the current AT. Also checks if
305 /// the current AT is unavailable (set to $0) and gives an error if it is.
306 /// This should be used in pseudo-instruction expansions which need AT.
307 unsigned getATReg(SMLoc Loc);
309 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
310 SmallVectorImpl<MCInst> &Instructions);
312 // Helper function that checks if the value of a vector index is within the
313 // boundaries of accepted values for each RegisterKind
314 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
315 bool validateMSAIndex(int Val, int RegKind);
317 // Selects a new architecture by updating the FeatureBits with the necessary
318 // info including implied dependencies.
319 // Internally, it clears all the feature bits related to *any* architecture
320 // and selects the new one using the ToggleFeature functionality of the
321 // MCSubtargetInfo object that handles implied dependencies. The reason we
322 // clear all the arch related bits manually is because ToggleFeature only
323 // clears the features that imply the feature being cleared and not the
324 // features implied by the feature being cleared. This is easier to see
326 // --------------------------------------------------
327 // | Feature | Implies |
328 // | -------------------------------------------------|
329 // | FeatureMips1 | None |
330 // | FeatureMips2 | FeatureMips1 |
331 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
332 // | FeatureMips4 | FeatureMips3 |
334 // --------------------------------------------------
336 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
337 // FeatureMipsGP64 | FeatureMips1)
338 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
339 void selectArch(StringRef ArchFeature) {
340 FeatureBitset FeatureBits = STI.getFeatureBits();
341 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
342 STI.setFeatureBits(FeatureBits);
343 setAvailableFeatures(
344 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
345 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
348 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
349 if (!(STI.getFeatureBits()[Feature])) {
350 setAvailableFeatures(
351 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
352 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
356 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
357 if (STI.getFeatureBits()[Feature]) {
358 setAvailableFeatures(
359 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
360 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
364 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
365 setFeatureBits(Feature, FeatureString);
366 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
369 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
370 clearFeatureBits(Feature, FeatureString);
371 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
375 enum MipsMatchResultTy {
376 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
377 #define GET_OPERAND_DIAGNOSTIC_TYPES
378 #include "MipsGenAsmMatcher.inc"
379 #undef GET_OPERAND_DIAGNOSTIC_TYPES
383 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
384 const MCInstrInfo &MII, const MCTargetOptions &Options)
385 : MCTargetAsmParser(), STI(sti),
386 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
387 sti.getCPU(), Options)) {
388 MCAsmParserExtension::Initialize(parser);
390 parser.addAliasForDirective(".asciiz", ".asciz");
392 // Initialize the set of available features.
393 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
395 // Remember the initial assembler options. The user can not modify these.
396 AssemblerOptions.push_back(
397 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
399 // Create an assembler options environment for the user to modify.
400 AssemblerOptions.push_back(
401 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
403 getTargetStreamer().updateABIInfo(*this);
405 if (!isABI_O32() && !useOddSPReg() != 0)
406 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
410 Triple TheTriple(sti.getTargetTriple());
411 if ((TheTriple.getArch() == Triple::mips) ||
412 (TheTriple.getArch() == Triple::mips64))
413 IsLittleEndian = false;
415 IsLittleEndian = true;
418 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
419 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
421 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
422 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
423 const MipsABIInfo &getABI() const { return ABI; }
424 bool isABI_N32() const { return ABI.IsN32(); }
425 bool isABI_N64() const { return ABI.IsN64(); }
426 bool isABI_O32() const { return ABI.IsO32(); }
427 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
429 bool useOddSPReg() const {
430 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
433 bool inMicroMipsMode() const {
434 return STI.getFeatureBits()[Mips::FeatureMicroMips];
436 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
437 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
438 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
439 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
440 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
441 bool hasMips32() const {
442 return STI.getFeatureBits()[Mips::FeatureMips32];
444 bool hasMips64() const {
445 return STI.getFeatureBits()[Mips::FeatureMips64];
447 bool hasMips32r2() const {
448 return STI.getFeatureBits()[Mips::FeatureMips32r2];
450 bool hasMips64r2() const {
451 return STI.getFeatureBits()[Mips::FeatureMips64r2];
453 bool hasMips32r3() const {
454 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
456 bool hasMips64r3() const {
457 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
459 bool hasMips32r5() const {
460 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
462 bool hasMips64r5() const {
463 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
465 bool hasMips32r6() const {
466 return STI.getFeatureBits()[Mips::FeatureMips32r6];
468 bool hasMips64r6() const {
469 return STI.getFeatureBits()[Mips::FeatureMips64r6];
472 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
473 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
474 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
475 bool hasCnMips() const {
476 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
479 bool inMips16Mode() const {
480 return STI.getFeatureBits()[Mips::FeatureMips16];
483 bool useSoftFloat() const {
484 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
487 /// Warn if RegIndex is the same as the current AT.
488 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
490 void warnIfNoMacro(SMLoc Loc);
492 bool isLittle() const { return IsLittleEndian; }
498 /// MipsOperand - Instances of this class represent a parsed Mips machine
500 class MipsOperand : public MCParsedAsmOperand {
502 /// Broad categories of register classes
503 /// The exact class is finalized by the render method.
505 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
506 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
508 RegKind_FCC = 4, /// FCC
509 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
510 RegKind_MSACtrl = 16, /// MSA control registers
511 RegKind_COP2 = 32, /// COP2
512 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
514 RegKind_CCR = 128, /// CCR
515 RegKind_HWRegs = 256, /// HWRegs
516 RegKind_COP3 = 512, /// COP3
517 RegKind_COP0 = 1024, /// COP0
518 /// Potentially any (e.g. $1)
519 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
520 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
521 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
526 k_Immediate, /// An immediate (possibly involving symbol references)
527 k_Memory, /// Base + Offset Memory Address
528 k_PhysRegister, /// A physical register from the Mips namespace
529 k_RegisterIndex, /// A register index in one or more RegKind.
530 k_Token, /// A simple token
531 k_RegList, /// A physical register list
532 k_RegPair /// A pair of physical register
536 MipsOperand(KindTy K, MipsAsmParser &Parser)
537 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
540 /// For diagnostics, and checking the assembler temporary
541 MipsAsmParser &AsmParser;
549 unsigned Num; /// Register Number
553 unsigned Index; /// Index into the register class
554 RegKind Kind; /// Bitfield of the kinds it could possibly be
555 const MCRegisterInfo *RegInfo;
568 SmallVector<unsigned, 10> *List;
573 struct PhysRegOp PhysReg;
574 struct RegIdxOp RegIdx;
577 struct RegListOp RegList;
580 SMLoc StartLoc, EndLoc;
582 /// Internal constructor for register kinds
583 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
584 const MCRegisterInfo *RegInfo,
586 MipsAsmParser &Parser) {
587 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
588 Op->RegIdx.Index = Index;
589 Op->RegIdx.RegInfo = RegInfo;
590 Op->RegIdx.Kind = RegKind;
597 /// Coerce the register to GPR32 and return the real register for the current
599 unsigned getGPR32Reg() const {
600 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
601 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
602 unsigned ClassID = Mips::GPR32RegClassID;
603 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
606 /// Coerce the register to GPR32 and return the real register for the current
608 unsigned getGPRMM16Reg() const {
609 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
610 unsigned ClassID = Mips::GPR32RegClassID;
611 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
614 /// Coerce the register to GPR64 and return the real register for the current
616 unsigned getGPR64Reg() const {
617 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
618 unsigned ClassID = Mips::GPR64RegClassID;
619 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
623 /// Coerce the register to AFGR64 and return the real register for the current
625 unsigned getAFGR64Reg() const {
626 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
627 if (RegIdx.Index % 2 != 0)
628 AsmParser.Warning(StartLoc, "Float register should be even.");
629 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
630 .getRegister(RegIdx.Index / 2);
633 /// Coerce the register to FGR64 and return the real register for the current
635 unsigned getFGR64Reg() const {
636 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
637 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
638 .getRegister(RegIdx.Index);
641 /// Coerce the register to FGR32 and return the real register for the current
643 unsigned getFGR32Reg() const {
644 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
645 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
646 .getRegister(RegIdx.Index);
649 /// Coerce the register to FGRH32 and return the real register for the current
651 unsigned getFGRH32Reg() const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
653 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
654 .getRegister(RegIdx.Index);
657 /// Coerce the register to FCC and return the real register for the current
659 unsigned getFCCReg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
661 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
662 .getRegister(RegIdx.Index);
665 /// Coerce the register to MSA128 and return the real register for the current
667 unsigned getMSA128Reg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
669 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
671 unsigned ClassID = Mips::MSA128BRegClassID;
672 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
675 /// Coerce the register to MSACtrl and return the real register for the
677 unsigned getMSACtrlReg() const {
678 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
679 unsigned ClassID = Mips::MSACtrlRegClassID;
680 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
683 /// Coerce the register to COP0 and return the real register for the
685 unsigned getCOP0Reg() const {
686 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
687 unsigned ClassID = Mips::COP0RegClassID;
688 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
691 /// Coerce the register to COP2 and return the real register for the
693 unsigned getCOP2Reg() const {
694 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
695 unsigned ClassID = Mips::COP2RegClassID;
696 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
699 /// Coerce the register to COP3 and return the real register for the
701 unsigned getCOP3Reg() const {
702 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
703 unsigned ClassID = Mips::COP3RegClassID;
704 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
707 /// Coerce the register to ACC64DSP and return the real register for the
709 unsigned getACC64DSPReg() const {
710 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
711 unsigned ClassID = Mips::ACC64DSPRegClassID;
712 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
715 /// Coerce the register to HI32DSP and return the real register for the
717 unsigned getHI32DSPReg() const {
718 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
719 unsigned ClassID = Mips::HI32DSPRegClassID;
720 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
723 /// Coerce the register to LO32DSP and return the real register for the
725 unsigned getLO32DSPReg() const {
726 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
727 unsigned ClassID = Mips::LO32DSPRegClassID;
728 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
731 /// Coerce the register to CCR and return the real register for the
733 unsigned getCCRReg() const {
734 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
735 unsigned ClassID = Mips::CCRRegClassID;
736 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
739 /// Coerce the register to HWRegs and return the real register for the
741 unsigned getHWRegsReg() const {
742 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
743 unsigned ClassID = Mips::HWRegsRegClassID;
744 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
748 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
749 // Add as immediate when possible. Null MCExpr = 0.
751 Inst.addOperand(MCOperand::createImm(0));
752 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
753 Inst.addOperand(MCOperand::createImm(CE->getValue()));
755 Inst.addOperand(MCOperand::createExpr(Expr));
758 void addRegOperands(MCInst &Inst, unsigned N) const {
759 llvm_unreachable("Use a custom parser instead");
762 /// Render the operand to an MCInst as a GPR32
763 /// Asserts if the wrong number of operands are requested, or the operand
764 /// is not a k_RegisterIndex compatible with RegKind_GPR
765 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
766 assert(N == 1 && "Invalid number of operands!");
767 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
770 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
771 assert(N == 1 && "Invalid number of operands!");
772 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
775 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
776 assert(N == 1 && "Invalid number of operands!");
777 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
780 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
781 assert(N == 1 && "Invalid number of operands!");
782 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
785 /// Render the operand to an MCInst as a GPR64
786 /// Asserts if the wrong number of operands are requested, or the operand
787 /// is not a k_RegisterIndex compatible with RegKind_GPR
788 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
789 assert(N == 1 && "Invalid number of operands!");
790 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
793 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
794 assert(N == 1 && "Invalid number of operands!");
795 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
798 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
799 assert(N == 1 && "Invalid number of operands!");
800 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
803 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
804 assert(N == 1 && "Invalid number of operands!");
805 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
806 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
807 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
808 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
812 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
813 assert(N == 1 && "Invalid number of operands!");
814 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
817 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
818 assert(N == 1 && "Invalid number of operands!");
819 Inst.addOperand(MCOperand::createReg(getFCCReg()));
822 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 1 && "Invalid number of operands!");
824 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
827 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
828 assert(N == 1 && "Invalid number of operands!");
829 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
832 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
833 assert(N == 1 && "Invalid number of operands!");
834 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
837 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
838 assert(N == 1 && "Invalid number of operands!");
839 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
842 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
843 assert(N == 1 && "Invalid number of operands!");
844 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
847 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 1 && "Invalid number of operands!");
849 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
852 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
853 assert(N == 1 && "Invalid number of operands!");
854 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
857 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
858 assert(N == 1 && "Invalid number of operands!");
859 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
862 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
863 assert(N == 1 && "Invalid number of operands!");
864 Inst.addOperand(MCOperand::createReg(getCCRReg()));
867 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
868 assert(N == 1 && "Invalid number of operands!");
869 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
872 void addImmOperands(MCInst &Inst, unsigned N) const {
873 assert(N == 1 && "Invalid number of operands!");
874 const MCExpr *Expr = getImm();
878 void addMemOperands(MCInst &Inst, unsigned N) const {
879 assert(N == 2 && "Invalid number of operands!");
881 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
883 const MCExpr *Expr = getMemOff();
887 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
888 assert(N == 2 && "Invalid number of operands!");
890 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
892 const MCExpr *Expr = getMemOff();
896 void addRegListOperands(MCInst &Inst, unsigned N) const {
897 assert(N == 1 && "Invalid number of operands!");
899 for (auto RegNo : getRegList())
900 Inst.addOperand(MCOperand::createReg(RegNo));
903 void addRegPairOperands(MCInst &Inst, unsigned N) const {
904 assert(N == 2 && "Invalid number of operands!");
905 unsigned RegNo = getRegPair();
906 Inst.addOperand(MCOperand::createReg(RegNo++));
907 Inst.addOperand(MCOperand::createReg(RegNo));
910 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
911 assert(N == 2 && "Invalid number of operands!");
912 for (auto RegNo : getRegList())
913 Inst.addOperand(MCOperand::createReg(RegNo));
916 bool isReg() const override {
917 // As a special case until we sort out the definition of div/divu, pretend
918 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
919 if (isGPRAsmReg() && RegIdx.Index == 0)
922 return Kind == k_PhysRegister;
924 bool isRegIdx() const { return Kind == k_RegisterIndex; }
925 bool isImm() const override { return Kind == k_Immediate; }
926 bool isConstantImm() const {
927 return isImm() && dyn_cast<MCConstantExpr>(getImm());
929 template <unsigned Bits> bool isUImm() const {
930 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
932 bool isToken() const override {
933 // Note: It's not possible to pretend that other operand kinds are tokens.
934 // The matcher emitter checks tokens first.
935 return Kind == k_Token;
937 bool isMem() const override { return Kind == k_Memory; }
938 bool isConstantMemOff() const {
939 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
941 template <unsigned Bits> bool isMemWithSimmOffset() const {
942 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
944 bool isMemWithGRPMM16Base() const {
945 return isMem() && getMemBase()->isMM16AsmReg();
947 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
948 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
949 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
951 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
952 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
953 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
954 && (getMemBase()->getGPR32Reg() == Mips::SP);
956 bool isRegList16() const {
960 int Size = RegList.List->size();
961 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
962 RegList.List->back() != Mips::RA)
965 int PrevReg = *RegList.List->begin();
966 for (int i = 1; i < Size - 1; i++) {
967 int Reg = (*(RegList.List))[i];
968 if ( Reg != PrevReg + 1)
975 bool isInvNum() const { return Kind == k_Immediate; }
976 bool isLSAImm() const {
977 if (!isConstantImm())
979 int64_t Val = getConstantImm();
980 return 1 <= Val && Val <= 4;
982 bool isRegList() const { return Kind == k_RegList; }
983 bool isMovePRegPair() const {
984 if (Kind != k_RegList || RegList.List->size() != 2)
987 unsigned R0 = RegList.List->front();
988 unsigned R1 = RegList.List->back();
990 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
991 (R0 == Mips::A1 && R1 == Mips::A3) ||
992 (R0 == Mips::A2 && R1 == Mips::A3) ||
993 (R0 == Mips::A0 && R1 == Mips::S5) ||
994 (R0 == Mips::A0 && R1 == Mips::S6) ||
995 (R0 == Mips::A0 && R1 == Mips::A1) ||
996 (R0 == Mips::A0 && R1 == Mips::A2) ||
997 (R0 == Mips::A0 && R1 == Mips::A3))
1003 StringRef getToken() const {
1004 assert(Kind == k_Token && "Invalid access!");
1005 return StringRef(Tok.Data, Tok.Length);
1007 bool isRegPair() const { return Kind == k_RegPair; }
1009 unsigned getReg() const override {
1010 // As a special case until we sort out the definition of div/divu, pretend
1011 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1012 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1013 RegIdx.Kind & RegKind_GPR)
1014 return getGPR32Reg(); // FIXME: GPR64 too
1016 assert(Kind == k_PhysRegister && "Invalid access!");
1020 const MCExpr *getImm() const {
1021 assert((Kind == k_Immediate) && "Invalid access!");
1025 int64_t getConstantImm() const {
1026 const MCExpr *Val = getImm();
1027 return static_cast<const MCConstantExpr *>(Val)->getValue();
1030 MipsOperand *getMemBase() const {
1031 assert((Kind == k_Memory) && "Invalid access!");
1035 const MCExpr *getMemOff() const {
1036 assert((Kind == k_Memory) && "Invalid access!");
1040 int64_t getConstantMemOff() const {
1041 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1044 const SmallVectorImpl<unsigned> &getRegList() const {
1045 assert((Kind == k_RegList) && "Invalid access!");
1046 return *(RegList.List);
1049 unsigned getRegPair() const {
1050 assert((Kind == k_RegPair) && "Invalid access!");
1051 return RegIdx.Index;
1054 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1055 MipsAsmParser &Parser) {
1056 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1057 Op->Tok.Data = Str.data();
1058 Op->Tok.Length = Str.size();
1064 /// Create a numeric register (e.g. $1). The exact register remains
1065 /// unresolved until an instruction successfully matches
1066 static std::unique_ptr<MipsOperand>
1067 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1068 SMLoc E, MipsAsmParser &Parser) {
1069 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1070 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1073 /// Create a register that is definitely a GPR.
1074 /// This is typically only used for named registers such as $gp.
1075 static std::unique_ptr<MipsOperand>
1076 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1077 MipsAsmParser &Parser) {
1078 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1081 /// Create a register that is definitely a FGR.
1082 /// This is typically only used for named registers such as $f0.
1083 static std::unique_ptr<MipsOperand>
1084 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1085 MipsAsmParser &Parser) {
1086 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1089 /// Create a register that is definitely a HWReg.
1090 /// This is typically only used for named registers such as $hwr_cpunum.
1091 static std::unique_ptr<MipsOperand>
1092 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1093 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1094 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1097 /// Create a register that is definitely an FCC.
1098 /// This is typically only used for named registers such as $fcc0.
1099 static std::unique_ptr<MipsOperand>
1100 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1101 MipsAsmParser &Parser) {
1102 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1105 /// Create a register that is definitely an ACC.
1106 /// This is typically only used for named registers such as $ac0.
1107 static std::unique_ptr<MipsOperand>
1108 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1109 MipsAsmParser &Parser) {
1110 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1113 /// Create a register that is definitely an MSA128.
1114 /// This is typically only used for named registers such as $w0.
1115 static std::unique_ptr<MipsOperand>
1116 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1117 SMLoc E, MipsAsmParser &Parser) {
1118 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1121 /// Create a register that is definitely an MSACtrl.
1122 /// This is typically only used for named registers such as $msaaccess.
1123 static std::unique_ptr<MipsOperand>
1124 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1125 SMLoc E, MipsAsmParser &Parser) {
1126 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1129 static std::unique_ptr<MipsOperand>
1130 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1131 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1138 static std::unique_ptr<MipsOperand>
1139 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1140 SMLoc E, MipsAsmParser &Parser) {
1141 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1142 Op->Mem.Base = Base.release();
1149 static std::unique_ptr<MipsOperand>
1150 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1151 MipsAsmParser &Parser) {
1152 assert (Regs.size() > 0 && "Empty list not allowed");
1154 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1155 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1156 Op->StartLoc = StartLoc;
1157 Op->EndLoc = EndLoc;
1161 static std::unique_ptr<MipsOperand>
1162 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1163 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1164 Op->RegIdx.Index = RegNo;
1170 bool isGPRAsmReg() const {
1171 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1173 bool isMM16AsmReg() const {
1174 if (!(isRegIdx() && RegIdx.Kind))
1176 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1177 || RegIdx.Index == 16 || RegIdx.Index == 17);
1179 bool isMM16AsmRegZero() const {
1180 if (!(isRegIdx() && RegIdx.Kind))
1182 return (RegIdx.Index == 0 ||
1183 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1184 RegIdx.Index == 17);
1186 bool isMM16AsmRegMoveP() const {
1187 if (!(isRegIdx() && RegIdx.Kind))
1189 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1190 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1192 bool isFGRAsmReg() const {
1193 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1194 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1196 bool isHWRegsAsmReg() const {
1197 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1199 bool isCCRAsmReg() const {
1200 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1202 bool isFCCAsmReg() const {
1203 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1205 if (!AsmParser.hasEightFccRegisters())
1206 return RegIdx.Index == 0;
1207 return RegIdx.Index <= 7;
1209 bool isACCAsmReg() const {
1210 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1212 bool isCOP0AsmReg() const {
1213 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1215 bool isCOP2AsmReg() const {
1216 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1218 bool isCOP3AsmReg() const {
1219 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1221 bool isMSA128AsmReg() const {
1222 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1224 bool isMSACtrlAsmReg() const {
1225 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1228 /// getStartLoc - Get the location of the first token of this operand.
1229 SMLoc getStartLoc() const override { return StartLoc; }
1230 /// getEndLoc - Get the location of the last token of this operand.
1231 SMLoc getEndLoc() const override { return EndLoc; }
1233 virtual ~MipsOperand() {
1241 delete RegList.List;
1242 case k_PhysRegister:
1243 case k_RegisterIndex:
1250 void print(raw_ostream &OS) const override {
1259 Mem.Base->print(OS);
1264 case k_PhysRegister:
1265 OS << "PhysReg<" << PhysReg.Num << ">";
1267 case k_RegisterIndex:
1268 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1275 for (auto Reg : (*RegList.List))
1280 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1284 }; // class MipsOperand
1288 extern const MCInstrDesc MipsInsts[];
1290 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1291 return MipsInsts[Opcode];
1294 static bool hasShortDelaySlot(unsigned Opcode) {
1297 case Mips::JALRS_MM:
1298 case Mips::JALRS16_MM:
1299 case Mips::BGEZALS_MM:
1300 case Mips::BLTZALS_MM:
1307 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1308 SmallVectorImpl<MCInst> &Instructions) {
1309 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1313 if (MCID.isBranch() || MCID.isCall()) {
1314 const unsigned Opcode = Inst.getOpcode();
1324 assert(hasCnMips() && "instruction only valid for octeon cpus");
1331 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1332 Offset = Inst.getOperand(2);
1333 if (!Offset.isImm())
1334 break; // We'll deal with this situation later on when applying fixups.
1335 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1336 return Error(IDLoc, "branch target out of range");
1337 if (OffsetToAlignment(Offset.getImm(),
1338 1LL << (inMicroMipsMode() ? 1 : 2)))
1339 return Error(IDLoc, "branch to misaligned address");
1353 case Mips::BGEZAL_MM:
1354 case Mips::BLTZAL_MM:
1357 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1358 Offset = Inst.getOperand(1);
1359 if (!Offset.isImm())
1360 break; // We'll deal with this situation later on when applying fixups.
1361 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1362 return Error(IDLoc, "branch target out of range");
1363 if (OffsetToAlignment(Offset.getImm(),
1364 1LL << (inMicroMipsMode() ? 1 : 2)))
1365 return Error(IDLoc, "branch to misaligned address");
1367 case Mips::BEQZ16_MM:
1368 case Mips::BNEZ16_MM:
1369 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1370 Offset = Inst.getOperand(1);
1371 if (!Offset.isImm())
1372 break; // We'll deal with this situation later on when applying fixups.
1373 if (!isIntN(8, Offset.getImm()))
1374 return Error(IDLoc, "branch target out of range");
1375 if (OffsetToAlignment(Offset.getImm(), 2LL))
1376 return Error(IDLoc, "branch to misaligned address");
1381 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1382 // We still accept it but it is a normal nop.
1383 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1384 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1385 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1390 const unsigned Opcode = Inst.getOpcode();
1402 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1403 // The offset is handled above
1404 Opnd = Inst.getOperand(1);
1406 return Error(IDLoc, "expected immediate operand kind");
1407 Imm = Opnd.getImm();
1408 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1409 Opcode == Mips::BBIT1 ? 63 : 31))
1410 return Error(IDLoc, "immediate operand value out of range");
1412 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1414 Inst.getOperand(1).setImm(Imm - 32);
1422 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1424 Opnd = Inst.getOperand(3);
1426 return Error(IDLoc, "expected immediate operand kind");
1427 Imm = Opnd.getImm();
1428 if (Imm < 0 || Imm > 31)
1429 return Error(IDLoc, "immediate operand value out of range");
1431 Opnd = Inst.getOperand(2);
1433 return Error(IDLoc, "expected immediate operand kind");
1434 Imm = Opnd.getImm();
1435 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1436 Opcode == Mips::EXTS ? 63 : 31))
1437 return Error(IDLoc, "immediate operand value out of range");
1439 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1440 Inst.getOperand(2).setImm(Imm - 32);
1446 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1447 Opnd = Inst.getOperand(2);
1449 return Error(IDLoc, "expected immediate operand kind");
1450 Imm = Opnd.getImm();
1451 if (!isInt<10>(Imm))
1452 return Error(IDLoc, "immediate operand value out of range");
1457 if (MCID.mayLoad() || MCID.mayStore()) {
1458 // Check the offset of memory operand, if it is a symbol
1459 // reference or immediate we may have to expand instructions.
1460 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1461 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1462 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1463 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1464 MCOperand &Op = Inst.getOperand(i);
1466 int MemOffset = Op.getImm();
1467 if (MemOffset < -32768 || MemOffset > 32767) {
1468 // Offset can't exceed 16bit value.
1469 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1472 } else if (Op.isExpr()) {
1473 const MCExpr *Expr = Op.getExpr();
1474 if (Expr->getKind() == MCExpr::SymbolRef) {
1475 const MCSymbolRefExpr *SR =
1476 static_cast<const MCSymbolRefExpr *>(Expr);
1477 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1479 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1482 } else if (!isEvaluated(Expr)) {
1483 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1491 if (inMicroMipsMode()) {
1492 if (MCID.mayLoad()) {
1493 // Try to create 16-bit GP relative load instruction.
1494 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1495 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1496 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1497 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1498 MCOperand &Op = Inst.getOperand(i);
1500 int MemOffset = Op.getImm();
1501 MCOperand &DstReg = Inst.getOperand(0);
1502 MCOperand &BaseReg = Inst.getOperand(1);
1503 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1504 getContext().getRegisterInfo()->getRegClass(
1505 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1506 BaseReg.getReg() == Mips::GP) {
1508 TmpInst.setLoc(IDLoc);
1509 TmpInst.setOpcode(Mips::LWGP_MM);
1510 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1511 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1512 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1513 Instructions.push_back(TmpInst);
1521 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1526 switch (Inst.getOpcode()) {
1529 case Mips::ADDIUS5_MM:
1530 Opnd = Inst.getOperand(2);
1532 return Error(IDLoc, "expected immediate operand kind");
1533 Imm = Opnd.getImm();
1534 if (Imm < -8 || Imm > 7)
1535 return Error(IDLoc, "immediate operand value out of range");
1537 case Mips::ADDIUSP_MM:
1538 Opnd = Inst.getOperand(0);
1540 return Error(IDLoc, "expected immediate operand kind");
1541 Imm = Opnd.getImm();
1542 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1544 return Error(IDLoc, "immediate operand value out of range");
1546 case Mips::SLL16_MM:
1547 case Mips::SRL16_MM:
1548 Opnd = Inst.getOperand(2);
1550 return Error(IDLoc, "expected immediate operand kind");
1551 Imm = Opnd.getImm();
1552 if (Imm < 1 || Imm > 8)
1553 return Error(IDLoc, "immediate operand value out of range");
1556 Opnd = Inst.getOperand(1);
1558 return Error(IDLoc, "expected immediate operand kind");
1559 Imm = Opnd.getImm();
1560 if (Imm < -1 || Imm > 126)
1561 return Error(IDLoc, "immediate operand value out of range");
1563 case Mips::ADDIUR2_MM:
1564 Opnd = Inst.getOperand(2);
1566 return Error(IDLoc, "expected immediate operand kind");
1567 Imm = Opnd.getImm();
1568 if (!(Imm == 1 || Imm == -1 ||
1569 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1570 return Error(IDLoc, "immediate operand value out of range");
1572 case Mips::ADDIUR1SP_MM:
1573 Opnd = Inst.getOperand(1);
1575 return Error(IDLoc, "expected immediate operand kind");
1576 Imm = Opnd.getImm();
1577 if (OffsetToAlignment(Imm, 4LL))
1578 return Error(IDLoc, "misaligned immediate operand value");
1579 if (Imm < 0 || Imm > 255)
1580 return Error(IDLoc, "immediate operand value out of range");
1582 case Mips::ANDI16_MM:
1583 Opnd = Inst.getOperand(2);
1585 return Error(IDLoc, "expected immediate operand kind");
1586 Imm = Opnd.getImm();
1587 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1588 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1589 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1590 return Error(IDLoc, "immediate operand value out of range");
1592 case Mips::LBU16_MM:
1593 Opnd = Inst.getOperand(2);
1595 return Error(IDLoc, "expected immediate operand kind");
1596 Imm = Opnd.getImm();
1597 if (Imm < -1 || Imm > 14)
1598 return Error(IDLoc, "immediate operand value out of range");
1601 Opnd = Inst.getOperand(2);
1603 return Error(IDLoc, "expected immediate operand kind");
1604 Imm = Opnd.getImm();
1605 if (Imm < 0 || Imm > 15)
1606 return Error(IDLoc, "immediate operand value out of range");
1608 case Mips::LHU16_MM:
1610 Opnd = Inst.getOperand(2);
1612 return Error(IDLoc, "expected immediate operand kind");
1613 Imm = Opnd.getImm();
1614 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1615 return Error(IDLoc, "immediate operand value out of range");
1619 Opnd = Inst.getOperand(2);
1621 return Error(IDLoc, "expected immediate operand kind");
1622 Imm = Opnd.getImm();
1623 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1624 return Error(IDLoc, "immediate operand value out of range");
1628 Opnd = Inst.getOperand(2);
1630 return Error(IDLoc, "expected immediate operand kind");
1631 Imm = Opnd.getImm();
1632 if (!isUInt<5>(Imm))
1633 return Error(IDLoc, "immediate operand value out of range");
1635 case Mips::ADDIUPC_MM:
1636 MCOperand Opnd = Inst.getOperand(1);
1638 return Error(IDLoc, "expected immediate operand kind");
1639 int Imm = Opnd.getImm();
1640 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1641 return Error(IDLoc, "immediate operand value out of range");
1646 if (needsExpansion(Inst)) {
1647 if (expandInstruction(Inst, IDLoc, Instructions))
1650 Instructions.push_back(Inst);
1652 // If this instruction has a delay slot and .set reorder is active,
1653 // emit a NOP after it.
1654 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1655 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1660 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1662 switch (Inst.getOpcode()) {
1663 case Mips::LoadImm32:
1664 case Mips::LoadImm64:
1665 case Mips::LoadAddrImm32:
1666 case Mips::LoadAddrReg32:
1667 case Mips::B_MM_Pseudo:
1670 case Mips::JalOneReg:
1671 case Mips::JalTwoReg:
1690 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1691 SmallVectorImpl<MCInst> &Instructions) {
1692 switch (Inst.getOpcode()) {
1693 default: llvm_unreachable("unimplemented expansion");
1694 case Mips::LoadImm32:
1695 return expandLoadImm(Inst, true, IDLoc, Instructions);
1696 case Mips::LoadImm64:
1697 return expandLoadImm(Inst, false, IDLoc, Instructions);
1698 case Mips::LoadAddrImm32:
1699 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1700 case Mips::LoadAddrReg32:
1701 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1702 case Mips::B_MM_Pseudo:
1703 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1706 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1707 case Mips::JalOneReg:
1708 case Mips::JalTwoReg:
1709 return expandJalWithRegs(Inst, IDLoc, Instructions);
1712 return expandBranchImm(Inst, IDLoc, Instructions);
1721 return expandCondBranches(Inst, IDLoc, Instructions);
1723 return expandUlhu(Inst, IDLoc, Instructions);
1725 return expandUlw(Inst, IDLoc, Instructions);
1730 template <unsigned ShiftAmount>
1731 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1732 SmallVectorImpl<MCInst> &Instructions) {
1734 if (ShiftAmount >= 32) {
1735 tmpInst.setOpcode(Mips::DSLL32);
1736 tmpInst.addOperand(MCOperand::createReg(RegNo));
1737 tmpInst.addOperand(MCOperand::createReg(RegNo));
1738 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1739 tmpInst.setLoc(IDLoc);
1740 Instructions.push_back(tmpInst);
1742 } else if (ShiftAmount > 0) {
1743 tmpInst.setOpcode(Mips::DSLL);
1744 tmpInst.addOperand(MCOperand::createReg(RegNo));
1745 tmpInst.addOperand(MCOperand::createReg(RegNo));
1746 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1747 tmpInst.setLoc(IDLoc);
1748 Instructions.push_back(tmpInst);
1751 // There's no need for an ORi if the immediate is 0.
1752 if (Operand.isImm() && Operand.getImm() == 0)
1755 tmpInst.setOpcode(Mips::ORi);
1756 tmpInst.addOperand(MCOperand::createReg(RegNo));
1757 tmpInst.addOperand(MCOperand::createReg(RegNo));
1758 tmpInst.addOperand(Operand);
1759 tmpInst.setLoc(IDLoc);
1760 Instructions.push_back(tmpInst);
1763 template <unsigned ShiftAmount>
1764 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1765 SmallVectorImpl<MCInst> &Instructions) {
1766 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1771 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1772 SmallVectorImpl<MCInst> &Instructions) {
1773 // Create a JALR instruction which is going to replace the pseudo-JAL.
1775 JalrInst.setLoc(IDLoc);
1776 const MCOperand FirstRegOp = Inst.getOperand(0);
1777 const unsigned Opcode = Inst.getOpcode();
1779 if (Opcode == Mips::JalOneReg) {
1780 // jal $rs => jalr $rs
1781 if (inMicroMipsMode()) {
1782 JalrInst.setOpcode(Mips::JALR16_MM);
1783 JalrInst.addOperand(FirstRegOp);
1785 JalrInst.setOpcode(Mips::JALR);
1786 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1787 JalrInst.addOperand(FirstRegOp);
1789 } else if (Opcode == Mips::JalTwoReg) {
1790 // jal $rd, $rs => jalr $rd, $rs
1791 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1792 JalrInst.addOperand(FirstRegOp);
1793 const MCOperand SecondRegOp = Inst.getOperand(1);
1794 JalrInst.addOperand(SecondRegOp);
1796 Instructions.push_back(JalrInst);
1798 // If .set reorder is active, emit a NOP after it.
1799 if (AssemblerOptions.back()->isReorder()) {
1800 // This is a 32-bit NOP because these 2 pseudo-instructions
1801 // do not have a short delay slot.
1803 NopInst.setOpcode(Mips::SLL);
1804 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1805 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1806 NopInst.addOperand(MCOperand::createImm(0));
1807 Instructions.push_back(NopInst);
1813 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1814 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1815 SmallVectorImpl<MCInst> &Instructions) {
1816 if (!Is32BitImm && !isGP64bit()) {
1817 Error(IDLoc, "instruction requires a 64-bit architecture");
1821 bool UseSrcReg = false;
1822 if (SrcReg != Mips::NoRegister)
1827 unsigned TmpReg = DstReg;
1828 if (UseSrcReg && (DstReg == SrcReg)) {
1829 // At this point we need AT to perform the expansions and we exit if it is
1831 unsigned ATReg = getATReg(IDLoc);
1837 tmpInst.setLoc(IDLoc);
1838 // FIXME: gas has a special case for values that are 000...1111, which
1839 // becomes a li -1 and then a dsrl
1840 if (0 <= ImmValue && ImmValue <= 65535) {
1841 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1842 // li d,j => ori d,$zero,j
1844 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1845 tmpInst.setOpcode(Mips::ORi);
1846 tmpInst.addOperand(MCOperand::createReg(DstReg));
1847 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1848 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1849 Instructions.push_back(tmpInst);
1850 } else if (ImmValue < 0 && ImmValue >= -32768) {
1851 // For negative signed 16-bit values (-32768 <= j < 0):
1852 // li d,j => addiu d,$zero,j
1854 SrcReg = Mips::ZERO;
1855 tmpInst.setOpcode(Mips::ADDiu);
1856 tmpInst.addOperand(MCOperand::createReg(DstReg));
1857 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1858 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1859 Instructions.push_back(tmpInst);
1860 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1861 warnIfNoMacro(IDLoc);
1863 // For all other values which are representable as a 32-bit integer:
1864 // li d,j => lui d,hi16(j)
1866 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1867 uint16_t Bits15To0 = ImmValue & 0xffff;
1869 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1870 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1872 tmpInst.setOpcode(Mips::ORi);
1873 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1874 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1875 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1876 tmpInst.setLoc(IDLoc);
1877 Instructions.push_back(tmpInst);
1878 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1879 createLShiftOri<16>(0, TmpReg, IDLoc, Instructions);
1881 tmpInst.setOpcode(Mips::LUi);
1882 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1883 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1884 Instructions.push_back(tmpInst);
1886 createLShiftOri<0>(Bits15To0, TmpReg, IDLoc, Instructions);
1889 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1891 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1893 Error(IDLoc, "instruction requires a 32-bit immediate");
1896 warnIfNoMacro(IDLoc);
1898 // <------- lo32 ------>
1899 // <------- hi32 ------>
1900 // <- hi16 -> <- lo16 ->
1901 // _________________________________
1903 // | 16-bits | 16-bits | 16-bits |
1904 // |__________|__________|__________|
1906 // For any 64-bit value that is representable as a 48-bit integer:
1907 // li d,j => lui d,hi16(j)
1908 // ori d,d,hi16(lo32(j))
1910 // ori d,d,lo16(lo32(j))
1911 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1912 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1913 uint16_t Bits15To0 = ImmValue & 0xffff;
1915 tmpInst.setOpcode(Mips::LUi);
1916 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1917 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1918 Instructions.push_back(tmpInst);
1919 createLShiftOri<0>(Bits31To16, TmpReg, IDLoc, Instructions);
1920 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1923 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1927 Error(IDLoc, "instruction requires a 32-bit immediate");
1930 warnIfNoMacro(IDLoc);
1932 // <------- hi32 ------> <------- lo32 ------>
1933 // <- hi16 -> <- lo16 ->
1934 // ___________________________________________
1936 // | 16-bits | 16-bits | 16-bits | 16-bits |
1937 // |__________|__________|__________|__________|
1939 // For all other values which are representable as a 64-bit integer:
1940 // li d,j => lui d,hi16(j)
1941 // ori d,d,lo16(hi32(j))
1943 // ori d,d,hi16(lo32(j))
1945 // ori d,d,lo16(lo32(j))
1946 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1947 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1948 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1949 uint16_t Bits15To0 = ImmValue & 0xffff;
1951 tmpInst.setOpcode(Mips::LUi);
1952 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1953 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1954 Instructions.push_back(tmpInst);
1955 createLShiftOri<0>(Bits47To32, TmpReg, IDLoc, Instructions);
1957 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1958 // two left shifts of 16 bits.
1959 if (Bits31To16 == 0) {
1960 createLShiftOri<32>(Bits15To0, TmpReg, IDLoc, Instructions);
1962 createLShiftOri<16>(Bits31To16, TmpReg, IDLoc, Instructions);
1963 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1967 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1972 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1973 SmallVectorImpl<MCInst> &Instructions) {
1974 const MCOperand &ImmOp = Inst.getOperand(1);
1975 assert(ImmOp.isImm() && "expected immediate operand kind");
1976 const MCOperand &DstRegOp = Inst.getOperand(0);
1977 assert(DstRegOp.isReg() && "expected register operand kind");
1979 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1980 Is32BitImm, IDLoc, Instructions))
1987 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1988 SmallVectorImpl<MCInst> &Instructions) {
1989 const MCOperand &DstRegOp = Inst.getOperand(0);
1990 assert(DstRegOp.isReg() && "expected register operand kind");
1992 const MCOperand &SrcRegOp = Inst.getOperand(1);
1993 assert(SrcRegOp.isReg() && "expected register operand kind");
1995 const MCOperand &ImmOp = Inst.getOperand(2);
1996 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1997 "expected immediate operand kind");
1998 if (!ImmOp.isImm()) {
1999 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
2000 SrcRegOp.getReg(), Is32BitImm, IDLoc,
2007 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
2008 Is32BitImm, IDLoc, Instructions))
2015 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2016 SmallVectorImpl<MCInst> &Instructions) {
2017 const MCOperand &DstRegOp = Inst.getOperand(0);
2018 assert(DstRegOp.isReg() && "expected register operand kind");
2020 const MCOperand &ImmOp = Inst.getOperand(1);
2021 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
2022 "expected immediate operand kind");
2023 if (!ImmOp.isImm()) {
2024 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
2025 Mips::NoRegister, Is32BitImm, IDLoc,
2032 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2033 Is32BitImm, IDLoc, Instructions))
2039 bool MipsAsmParser::loadAndAddSymbolAddress(
2040 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2041 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2042 warnIfNoMacro(IDLoc);
2044 if (Is32BitSym && isABI_N64())
2045 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
2048 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2049 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2050 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2051 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2052 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2054 bool UseSrcReg = SrcReg != Mips::NoRegister;
2056 unsigned TmpReg = DstReg;
2057 if (UseSrcReg && (DstReg == SrcReg)) {
2058 // At this point we need AT to perform the expansions and we exit if it is
2060 unsigned ATReg = getATReg(IDLoc);
2067 // If it's a 64-bit architecture, expand to:
2068 // la d,sym => lui d,highest(sym)
2069 // ori d,d,higher(sym)
2071 // ori d,d,hi16(sym)
2073 // ori d,d,lo16(sym)
2074 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2075 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2076 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2077 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2079 tmpInst.setOpcode(Mips::LUi);
2080 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2081 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
2082 Instructions.push_back(tmpInst);
2084 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), TmpReg, SMLoc(),
2086 createLShiftOri<16>(MCOperand::createExpr(HiExpr), TmpReg, SMLoc(),
2088 createLShiftOri<16>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2091 // Otherwise, expand to:
2092 // la d,sym => lui d,hi16(sym)
2093 // ori d,d,lo16(sym)
2094 tmpInst.setOpcode(Mips::LUi);
2095 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2096 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2097 Instructions.push_back(tmpInst);
2099 createLShiftOri<0>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2104 createAddu(DstReg, TmpReg, SrcReg, !Is32BitSym, Instructions);
2109 bool MipsAsmParser::expandUncondBranchMMPseudo(
2110 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2111 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2112 "unexpected number of operands");
2114 MCOperand Offset = Inst.getOperand(0);
2115 if (Offset.isExpr()) {
2117 Inst.setOpcode(Mips::BEQ_MM);
2118 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2119 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2120 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2122 assert(Offset.isImm() && "expected immediate operand kind");
2123 if (isIntN(11, Offset.getImm())) {
2124 // If offset fits into 11 bits then this instruction becomes microMIPS
2125 // 16-bit unconditional branch instruction.
2126 Inst.setOpcode(Mips::B16_MM);
2128 if (!isIntN(17, Offset.getImm()))
2129 Error(IDLoc, "branch target out of range");
2130 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2131 Error(IDLoc, "branch to misaligned address");
2133 Inst.setOpcode(Mips::BEQ_MM);
2134 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2135 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2136 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2139 Instructions.push_back(Inst);
2141 // If .set reorder is active, emit a NOP after the branch instruction.
2142 if (AssemblerOptions.back()->isReorder())
2143 createNop(true, IDLoc, Instructions);
2148 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2149 SmallVectorImpl<MCInst> &Instructions) {
2150 const MCOperand &DstRegOp = Inst.getOperand(0);
2151 assert(DstRegOp.isReg() && "expected register operand kind");
2153 const MCOperand &ImmOp = Inst.getOperand(1);
2154 assert(ImmOp.isImm() && "expected immediate operand kind");
2156 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2157 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2159 unsigned OpCode = 0;
2160 switch(Inst.getOpcode()) {
2168 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2172 int64_t ImmValue = ImmOp.getImm();
2173 if (ImmValue == 0) {
2175 BranchInst.setOpcode(OpCode);
2176 BranchInst.addOperand(DstRegOp);
2177 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2178 BranchInst.addOperand(MemOffsetOp);
2179 Instructions.push_back(BranchInst);
2181 warnIfNoMacro(IDLoc);
2183 unsigned ATReg = getATReg(IDLoc);
2187 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2192 BranchInst.setOpcode(OpCode);
2193 BranchInst.addOperand(DstRegOp);
2194 BranchInst.addOperand(MCOperand::createReg(ATReg));
2195 BranchInst.addOperand(MemOffsetOp);
2196 Instructions.push_back(BranchInst);
2201 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2202 SmallVectorImpl<MCInst> &Instructions,
2203 bool isLoad, bool isImmOpnd) {
2205 unsigned ImmOffset, HiOffset, LoOffset;
2206 const MCExpr *ExprOffset;
2208 // 1st operand is either the source or destination register.
2209 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2210 unsigned RegOpNum = Inst.getOperand(0).getReg();
2211 // 2nd operand is the base register.
2212 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2213 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2214 // 3rd operand is either an immediate or expression.
2216 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2217 ImmOffset = Inst.getOperand(2).getImm();
2218 LoOffset = ImmOffset & 0x0000ffff;
2219 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2220 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2221 if (LoOffset & 0x8000)
2224 ExprOffset = Inst.getOperand(2).getExpr();
2225 // All instructions will have the same location.
2226 TempInst.setLoc(IDLoc);
2227 // These are some of the types of expansions we perform here:
2228 // 1) lw $8, sym => lui $8, %hi(sym)
2229 // lw $8, %lo(sym)($8)
2230 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2232 // lw $8, %lo(offset)($9)
2233 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2235 // lw $8, %lo(offset)($at)
2236 // 4) sw $8, sym => lui $at, %hi(sym)
2237 // sw $8, %lo(sym)($at)
2238 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2240 // sw $8, %lo(offset)($at)
2241 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2242 // ldc1 $f0, %lo(sym)($at)
2244 // For load instructions we can use the destination register as a temporary
2245 // if base and dst are different (examples 1 and 2) and if the base register
2246 // is general purpose otherwise we must use $at (example 6) and error if it's
2247 // not available. For stores we must use $at (examples 4 and 5) because we
2248 // must not clobber the source register setting up the offset.
2249 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2250 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2251 unsigned RegClassIDOp0 =
2252 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2253 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2254 (RegClassIDOp0 == Mips::GPR64RegClassID);
2255 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2256 TmpRegNum = RegOpNum;
2258 // At this point we need AT to perform the expansions and we exit if it is
2260 TmpRegNum = getATReg(IDLoc);
2265 TempInst.setOpcode(Mips::LUi);
2266 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2268 TempInst.addOperand(MCOperand::createImm(HiOffset));
2270 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2271 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2273 // Add the instruction to the list.
2274 Instructions.push_back(TempInst);
2275 // Prepare TempInst for next instruction.
2277 // Add temp register to base.
2278 if (BaseRegNum != Mips::ZERO) {
2279 TempInst.setOpcode(Mips::ADDu);
2280 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2281 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2282 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2283 Instructions.push_back(TempInst);
2286 // And finally, create original instruction with low part
2287 // of offset and new base.
2288 TempInst.setOpcode(Inst.getOpcode());
2289 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2290 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2292 TempInst.addOperand(MCOperand::createImm(LoOffset));
2294 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2295 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2297 Instructions.push_back(TempInst);
2302 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2303 SmallVectorImpl<MCInst> &Instructions) {
2304 unsigned OpNum = Inst.getNumOperands();
2305 unsigned Opcode = Inst.getOpcode();
2306 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2308 assert (Inst.getOperand(OpNum - 1).isImm() &&
2309 Inst.getOperand(OpNum - 2).isReg() &&
2310 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2312 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2313 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2314 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2315 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2316 // It can be implemented as SWM16 or LWM16 instruction.
2317 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2319 Inst.setOpcode(NewOpcode);
2320 Instructions.push_back(Inst);
2324 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2325 SmallVectorImpl<MCInst> &Instructions) {
2326 unsigned PseudoOpcode = Inst.getOpcode();
2327 unsigned SrcReg = Inst.getOperand(0).getReg();
2328 unsigned TrgReg = Inst.getOperand(1).getReg();
2329 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2331 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2332 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2334 switch (PseudoOpcode) {
2337 AcceptsEquality = false;
2338 ReverseOrderSLT = false;
2339 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2340 ZeroSrcOpcode = Mips::BGTZ;
2341 ZeroTrgOpcode = Mips::BLTZ;
2345 AcceptsEquality = true;
2346 ReverseOrderSLT = true;
2347 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2348 ZeroSrcOpcode = Mips::BGEZ;
2349 ZeroTrgOpcode = Mips::BLEZ;
2353 AcceptsEquality = true;
2354 ReverseOrderSLT = false;
2355 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2356 ZeroSrcOpcode = Mips::BLEZ;
2357 ZeroTrgOpcode = Mips::BGEZ;
2361 AcceptsEquality = false;
2362 ReverseOrderSLT = true;
2363 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2364 ZeroSrcOpcode = Mips::BLTZ;
2365 ZeroTrgOpcode = Mips::BGTZ;
2368 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2372 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2373 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2374 if (IsSrcRegZero && IsTrgRegZero) {
2375 // FIXME: All of these Opcode-specific if's are needed for compatibility
2376 // with GAS' behaviour. However, they may not generate the most efficient
2377 // code in some circumstances.
2378 if (PseudoOpcode == Mips::BLT) {
2379 BranchInst.setOpcode(Mips::BLTZ);
2380 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2381 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2382 Instructions.push_back(BranchInst);
2385 if (PseudoOpcode == Mips::BLE) {
2386 BranchInst.setOpcode(Mips::BLEZ);
2387 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2388 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2389 Instructions.push_back(BranchInst);
2390 Warning(IDLoc, "branch is always taken");
2393 if (PseudoOpcode == Mips::BGE) {
2394 BranchInst.setOpcode(Mips::BGEZ);
2395 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2396 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2397 Instructions.push_back(BranchInst);
2398 Warning(IDLoc, "branch is always taken");
2401 if (PseudoOpcode == Mips::BGT) {
2402 BranchInst.setOpcode(Mips::BGTZ);
2403 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2404 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2405 Instructions.push_back(BranchInst);
2408 if (PseudoOpcode == Mips::BGTU) {
2409 BranchInst.setOpcode(Mips::BNE);
2410 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2411 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2412 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2413 Instructions.push_back(BranchInst);
2416 if (AcceptsEquality) {
2417 // If both registers are $0 and the pseudo-branch accepts equality, it
2418 // will always be taken, so we emit an unconditional branch.
2419 BranchInst.setOpcode(Mips::BEQ);
2420 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2421 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2422 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2423 Instructions.push_back(BranchInst);
2424 Warning(IDLoc, "branch is always taken");
2427 // If both registers are $0 and the pseudo-branch does not accept
2428 // equality, it will never be taken, so we don't have to emit anything.
2431 if (IsSrcRegZero || IsTrgRegZero) {
2432 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2433 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2434 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2435 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2436 // the pseudo-branch will never be taken, so we don't emit anything.
2437 // This only applies to unsigned pseudo-branches.
2440 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2441 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2442 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2443 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2444 // the pseudo-branch will always be taken, so we emit an unconditional
2446 // This only applies to unsigned pseudo-branches.
2447 BranchInst.setOpcode(Mips::BEQ);
2448 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2449 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2450 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2451 Instructions.push_back(BranchInst);
2452 Warning(IDLoc, "branch is always taken");
2456 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2457 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2458 // the pseudo-branch will be taken only when the non-zero register is
2459 // different from 0, so we emit a BNEZ.
2461 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2462 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2463 // the pseudo-branch will be taken only when the non-zero register is
2464 // equal to 0, so we emit a BEQZ.
2466 // Because only BLEU and BGEU branch on equality, we can use the
2467 // AcceptsEquality variable to decide when to emit the BEQZ.
2468 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2469 BranchInst.addOperand(
2470 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2471 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2472 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2473 Instructions.push_back(BranchInst);
2476 // If we have a signed pseudo-branch and one of the registers is $0,
2477 // we can use an appropriate compare-to-zero branch. We select which one
2478 // to use in the switch statement above.
2479 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2480 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2481 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2482 Instructions.push_back(BranchInst);
2486 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2487 // expansions. If it is not available, we return.
2488 unsigned ATRegNum = getATReg(IDLoc);
2492 warnIfNoMacro(IDLoc);
2494 // SLT fits well with 2 of our 4 pseudo-branches:
2495 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2496 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2497 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2498 // This is accomplished by using a BNEZ with the result of the SLT.
2500 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2501 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2502 // Because only BGE and BLE branch on equality, we can use the
2503 // AcceptsEquality variable to decide when to emit the BEQZ.
2504 // Note that the order of the SLT arguments doesn't change between
2507 // The same applies to the unsigned variants, except that SLTu is used
2510 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2511 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2512 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2513 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2514 Instructions.push_back(SetInst);
2516 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2517 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2518 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2519 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2520 Instructions.push_back(BranchInst);
2524 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2525 SmallVectorImpl<MCInst> &Instructions) {
2526 if (hasMips32r6() || hasMips64r6()) {
2527 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2531 warnIfNoMacro(IDLoc);
2533 const MCOperand &DstRegOp = Inst.getOperand(0);
2534 assert(DstRegOp.isReg() && "expected register operand kind");
2536 const MCOperand &SrcRegOp = Inst.getOperand(1);
2537 assert(SrcRegOp.isReg() && "expected register operand kind");
2539 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2540 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2542 unsigned DstReg = DstRegOp.getReg();
2543 unsigned SrcReg = SrcRegOp.getReg();
2544 int64_t OffsetValue = OffsetImmOp.getImm();
2546 // NOTE: We always need AT for ULHU, as it is always used as the source
2547 // register for one of the LBu's.
2548 unsigned ATReg = getATReg(IDLoc);
2552 // When the value of offset+1 does not fit in 16 bits, we have to load the
2553 // offset in AT, (D)ADDu the original source register (if there was one), and
2554 // then use AT as the source register for the 2 generated LBu's.
2555 bool LoadedOffsetInAT = false;
2556 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2557 LoadedOffsetInAT = true;
2559 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2560 IDLoc, Instructions))
2563 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2564 // because it will make our output more similar to GAS'. For example,
2565 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2566 // instead of just an "ori $1, $9, 32768".
2567 // NOTE: If there is no source register specified in the ULHU, the parser
2568 // will interpret it as $0.
2569 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2570 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2573 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2574 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2575 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2577 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2579 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2580 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2582 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2583 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2586 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2589 TmpInst.setOpcode(Mips::LBu);
2590 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2591 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2592 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2593 Instructions.push_back(TmpInst);
2596 TmpInst.setOpcode(Mips::LBu);
2597 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2598 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2599 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2600 Instructions.push_back(TmpInst);
2603 TmpInst.setOpcode(Mips::SLL);
2604 TmpInst.addOperand(MCOperand::createReg(SllReg));
2605 TmpInst.addOperand(MCOperand::createReg(SllReg));
2606 TmpInst.addOperand(MCOperand::createImm(8));
2607 Instructions.push_back(TmpInst);
2610 TmpInst.setOpcode(Mips::OR);
2611 TmpInst.addOperand(MCOperand::createReg(DstReg));
2612 TmpInst.addOperand(MCOperand::createReg(DstReg));
2613 TmpInst.addOperand(MCOperand::createReg(ATReg));
2614 Instructions.push_back(TmpInst);
2619 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2620 SmallVectorImpl<MCInst> &Instructions) {
2621 if (hasMips32r6() || hasMips64r6()) {
2622 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2626 const MCOperand &DstRegOp = Inst.getOperand(0);
2627 assert(DstRegOp.isReg() && "expected register operand kind");
2629 const MCOperand &SrcRegOp = Inst.getOperand(1);
2630 assert(SrcRegOp.isReg() && "expected register operand kind");
2632 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2633 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2635 unsigned SrcReg = SrcRegOp.getReg();
2636 int64_t OffsetValue = OffsetImmOp.getImm();
2639 // When the value of offset+3 does not fit in 16 bits, we have to load the
2640 // offset in AT, (D)ADDu the original source register (if there was one), and
2641 // then use AT as the source register for the generated LWL and LWR.
2642 bool LoadedOffsetInAT = false;
2643 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
2644 ATReg = getATReg(IDLoc);
2647 LoadedOffsetInAT = true;
2649 warnIfNoMacro(IDLoc);
2651 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2652 IDLoc, Instructions))
2655 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2656 // because it will make our output more similar to GAS'. For example,
2657 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2658 // instead of just an "ori $1, $9, 32768".
2659 // NOTE: If there is no source register specified in the ULW, the parser
2660 // will interpret it as $0.
2661 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2662 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2665 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2666 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
2668 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2669 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2671 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2672 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2675 MCInst LeftLoadInst;
2676 LeftLoadInst.setOpcode(Mips::LWL);
2677 LeftLoadInst.addOperand(DstRegOp);
2678 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2679 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
2680 Instructions.push_back(LeftLoadInst);
2682 MCInst RightLoadInst;
2683 RightLoadInst.setOpcode(Mips::LWR);
2684 RightLoadInst.addOperand(DstRegOp);
2685 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2686 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
2687 Instructions.push_back(RightLoadInst);
2692 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2693 SmallVectorImpl<MCInst> &Instructions) {
2695 if (hasShortDelaySlot) {
2696 NopInst.setOpcode(Mips::MOVE16_MM);
2697 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2698 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2700 NopInst.setOpcode(Mips::SLL);
2701 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2702 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2703 NopInst.addOperand(MCOperand::createImm(0));
2705 Instructions.push_back(NopInst);
2708 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2709 unsigned TrgReg, bool Is64Bit,
2710 SmallVectorImpl<MCInst> &Instructions) {
2712 AdduInst.setOpcode(Is64Bit ? Mips::DADDu : Mips::ADDu);
2713 AdduInst.addOperand(MCOperand::createReg(DstReg));
2714 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2715 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2716 Instructions.push_back(AdduInst);
2719 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2720 // As described by the Mips32r2 spec, the registers Rd and Rs for
2721 // jalr.hb must be different.
2722 unsigned Opcode = Inst.getOpcode();
2724 if (Opcode == Mips::JALR_HB &&
2725 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2726 return Match_RequiresDifferentSrcAndDst;
2728 return Match_Success;
2731 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2732 OperandVector &Operands,
2734 uint64_t &ErrorInfo,
2735 bool MatchingInlineAsm) {
2738 SmallVector<MCInst, 8> Instructions;
2739 unsigned MatchResult =
2740 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2742 switch (MatchResult) {
2743 case Match_Success: {
2744 if (processInstruction(Inst, IDLoc, Instructions))
2746 for (unsigned i = 0; i < Instructions.size(); i++)
2747 Out.EmitInstruction(Instructions[i], STI);
2750 case Match_MissingFeature:
2751 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2753 case Match_InvalidOperand: {
2754 SMLoc ErrorLoc = IDLoc;
2755 if (ErrorInfo != ~0ULL) {
2756 if (ErrorInfo >= Operands.size())
2757 return Error(IDLoc, "too few operands for instruction");
2759 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2760 if (ErrorLoc == SMLoc())
2764 return Error(ErrorLoc, "invalid operand for instruction");
2766 case Match_MnemonicFail:
2767 return Error(IDLoc, "invalid instruction");
2768 case Match_RequiresDifferentSrcAndDst:
2769 return Error(IDLoc, "source and destination must be different");
2772 llvm_unreachable("Implement any new match types added!");
2775 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2776 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2777 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2778 ") without \".set noat\"");
2781 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2782 if (!AssemblerOptions.back()->isMacro())
2783 Warning(Loc, "macro instruction expanded into multiple instructions");
2787 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2788 SMRange Range, bool ShowColors) {
2789 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2790 Range, SMFixIt(Range, FixMsg),
2794 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2797 CC = StringSwitch<unsigned>(Name)
2833 if (!(isABI_N32() || isABI_N64()))
2836 if (12 <= CC && CC <= 15) {
2837 // Name is one of t4-t7
2838 AsmToken RegTok = getLexer().peekTok();
2839 SMRange RegRange = RegTok.getLocRange();
2841 StringRef FixedName = StringSwitch<StringRef>(Name)
2847 assert(FixedName != "" && "Register name is not one of t4-t7.");
2849 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2850 "Did you mean $" + FixedName + "?", RegRange);
2853 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2854 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2855 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2856 if (8 <= CC && CC <= 11)
2860 CC = StringSwitch<unsigned>(Name)
2872 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2875 CC = StringSwitch<unsigned>(Name)
2876 .Case("hwr_cpunum", 0)
2877 .Case("hwr_synci_step", 1)
2879 .Case("hwr_ccres", 3)
2880 .Case("hwr_ulr", 29)
2886 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2888 if (Name[0] == 'f') {
2889 StringRef NumString = Name.substr(1);
2891 if (NumString.getAsInteger(10, IntVal))
2892 return -1; // This is not an integer.
2893 if (IntVal > 31) // Maximum index for fpu register.
2900 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2902 if (Name.startswith("fcc")) {
2903 StringRef NumString = Name.substr(3);
2905 if (NumString.getAsInteger(10, IntVal))
2906 return -1; // This is not an integer.
2907 if (IntVal > 7) // There are only 8 fcc registers.
2914 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2916 if (Name.startswith("ac")) {
2917 StringRef NumString = Name.substr(2);
2919 if (NumString.getAsInteger(10, IntVal))
2920 return -1; // This is not an integer.
2921 if (IntVal > 3) // There are only 3 acc registers.
2928 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2931 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2940 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2943 CC = StringSwitch<unsigned>(Name)
2946 .Case("msaaccess", 2)
2948 .Case("msamodify", 4)
2949 .Case("msarequest", 5)
2951 .Case("msaunmap", 7)
2957 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2958 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2960 reportParseError(Loc,
2961 "pseudo-instruction requires $at, which is not available");
2964 unsigned AT = getReg(
2965 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2969 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2970 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2973 unsigned MipsAsmParser::getGPR(int RegNo) {
2974 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2978 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2980 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2983 return getReg(RegClass, RegNum);
2986 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2987 MCAsmParser &Parser = getParser();
2988 DEBUG(dbgs() << "parseOperand\n");
2990 // Check if the current operand has a custom associated parser, if so, try to
2991 // custom parse the operand, or fallback to the general approach.
2992 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2993 if (ResTy == MatchOperand_Success)
2995 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2996 // there was a match, but an error occurred, in which case, just return that
2997 // the operand parsing failed.
2998 if (ResTy == MatchOperand_ParseFail)
3001 DEBUG(dbgs() << ".. Generic Parser\n");
3003 switch (getLexer().getKind()) {
3005 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3007 case AsmToken::Dollar: {
3008 // Parse the register.
3009 SMLoc S = Parser.getTok().getLoc();
3011 // Almost all registers have been parsed by custom parsers. There is only
3012 // one exception to this. $zero (and it's alias $0) will reach this point
3013 // for div, divu, and similar instructions because it is not an operand
3014 // to the instruction definition but an explicit register. Special case
3015 // this situation for now.
3016 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3019 // Maybe it is a symbol reference.
3020 StringRef Identifier;
3021 if (Parser.parseIdentifier(Identifier))
3024 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3025 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3026 // Otherwise create a symbol reference.
3028 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3030 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3033 // Else drop to expression parsing.
3034 case AsmToken::LParen:
3035 case AsmToken::Minus:
3036 case AsmToken::Plus:
3037 case AsmToken::Integer:
3038 case AsmToken::Tilde:
3039 case AsmToken::String: {
3040 DEBUG(dbgs() << ".. generic integer\n");
3041 OperandMatchResultTy ResTy = parseImm(Operands);
3042 return ResTy != MatchOperand_Success;
3044 case AsmToken::Percent: {
3045 // It is a symbol reference or constant expression.
3046 const MCExpr *IdVal;
3047 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3048 if (parseRelocOperand(IdVal))
3051 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3053 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3055 } // case AsmToken::Percent
3056 } // switch(getLexer().getKind())
3060 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3061 StringRef RelocStr) {
3063 // Check the type of the expression.
3064 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3065 // It's a constant, evaluate reloc value.
3067 switch (getVariantKind(RelocStr)) {
3068 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3069 // Get the 1st 16-bits.
3070 Val = MCE->getValue() & 0xffff;
3072 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3073 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3074 // 16 bits being negative.
3075 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3077 case MCSymbolRefExpr::VK_Mips_HIGHER:
3078 // Get the 3rd 16-bits.
3079 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3081 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3082 // Get the 4th 16-bits.
3083 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3086 report_fatal_error("unsupported reloc value");
3088 return MCConstantExpr::create(Val, getContext());
3091 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3092 // It's a symbol, create a symbolic expression from the symbol.
3093 const MCSymbol *Symbol = &MSRE->getSymbol();
3094 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3095 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3099 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3100 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3102 // Try to create target expression.
3103 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3104 return MipsMCExpr::create(VK, Expr, getContext());
3106 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3107 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3108 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3112 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3113 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3114 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3117 // Just return the original expression.
3121 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3123 switch (Expr->getKind()) {
3124 case MCExpr::Constant:
3126 case MCExpr::SymbolRef:
3127 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3128 case MCExpr::Binary:
3129 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3130 if (!isEvaluated(BE->getLHS()))
3132 return isEvaluated(BE->getRHS());
3135 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3136 case MCExpr::Target:
3142 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3143 MCAsmParser &Parser = getParser();
3144 Parser.Lex(); // Eat the % token.
3145 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3146 if (Tok.isNot(AsmToken::Identifier))
3149 std::string Str = Tok.getIdentifier();
3151 Parser.Lex(); // Eat the identifier.
3152 // Now make an expression from the rest of the operand.
3153 const MCExpr *IdVal;
3156 if (getLexer().getKind() == AsmToken::LParen) {
3158 Parser.Lex(); // Eat the '(' token.
3159 if (getLexer().getKind() == AsmToken::Percent) {
3160 Parser.Lex(); // Eat the % token.
3161 const AsmToken &nextTok = Parser.getTok();
3162 if (nextTok.isNot(AsmToken::Identifier))
3165 Str += nextTok.getIdentifier();
3166 Parser.Lex(); // Eat the identifier.
3167 if (getLexer().getKind() != AsmToken::LParen)
3172 if (getParser().parseParenExpression(IdVal, EndLoc))
3175 while (getLexer().getKind() == AsmToken::RParen)
3176 Parser.Lex(); // Eat the ')' token.
3179 return true; // Parenthesis must follow the relocation operand.
3181 Res = evaluateRelocExpr(IdVal, Str);
3185 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3187 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3188 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3189 if (ResTy == MatchOperand_Success) {
3190 assert(Operands.size() == 1);
3191 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3192 StartLoc = Operand.getStartLoc();
3193 EndLoc = Operand.getEndLoc();
3195 // AFAIK, we only support numeric registers and named GPR's in CFI
3197 // Don't worry about eating tokens before failing. Using an unrecognised
3198 // register is a parse error.
3199 if (Operand.isGPRAsmReg()) {
3200 // Resolve to GPR32 or GPR64 appropriately.
3201 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3204 return (RegNo == (unsigned)-1);
3207 assert(Operands.size() == 0);
3208 return (RegNo == (unsigned)-1);
3211 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3212 MCAsmParser &Parser = getParser();
3215 unsigned NumOfLParen = 0;
3217 while (getLexer().getKind() == AsmToken::LParen) {
3222 switch (getLexer().getKind()) {
3225 case AsmToken::Identifier:
3226 case AsmToken::LParen:
3227 case AsmToken::Integer:
3228 case AsmToken::Minus:
3229 case AsmToken::Plus:
3231 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3233 Result = (getParser().parseExpression(Res));
3234 while (getLexer().getKind() == AsmToken::RParen)
3237 case AsmToken::Percent:
3238 Result = parseRelocOperand(Res);
3243 MipsAsmParser::OperandMatchResultTy
3244 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3245 MCAsmParser &Parser = getParser();
3246 DEBUG(dbgs() << "parseMemOperand\n");
3247 const MCExpr *IdVal = nullptr;
3249 bool isParenExpr = false;
3250 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3251 // First operand is the offset.
3252 S = Parser.getTok().getLoc();
3254 if (getLexer().getKind() == AsmToken::LParen) {
3259 if (getLexer().getKind() != AsmToken::Dollar) {
3260 if (parseMemOffset(IdVal, isParenExpr))
3261 return MatchOperand_ParseFail;
3263 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3264 if (Tok.isNot(AsmToken::LParen)) {
3265 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3266 if (Mnemonic.getToken() == "la") {
3268 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3269 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3270 return MatchOperand_Success;
3272 if (Tok.is(AsmToken::EndOfStatement)) {
3274 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3276 // Zero register assumed, add a memory operand with ZERO as its base.
3277 // "Base" will be managed by k_Memory.
3278 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3281 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3282 return MatchOperand_Success;
3284 Error(Parser.getTok().getLoc(), "'(' expected");
3285 return MatchOperand_ParseFail;
3288 Parser.Lex(); // Eat the '(' token.
3291 Res = parseAnyRegister(Operands);
3292 if (Res != MatchOperand_Success)
3295 if (Parser.getTok().isNot(AsmToken::RParen)) {
3296 Error(Parser.getTok().getLoc(), "')' expected");
3297 return MatchOperand_ParseFail;
3300 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3302 Parser.Lex(); // Eat the ')' token.
3305 IdVal = MCConstantExpr::create(0, getContext());
3307 // Replace the register operand with the memory operand.
3308 std::unique_ptr<MipsOperand> op(
3309 static_cast<MipsOperand *>(Operands.back().release()));
3310 // Remove the register from the operands.
3311 // "op" will be managed by k_Memory.
3312 Operands.pop_back();
3313 // Add the memory operand.
3314 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3316 if (IdVal->evaluateAsAbsolute(Imm))
3317 IdVal = MCConstantExpr::create(Imm, getContext());
3318 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3319 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3323 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3324 return MatchOperand_Success;
3327 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3328 MCAsmParser &Parser = getParser();
3329 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3331 SMLoc S = Parser.getTok().getLoc();
3333 if (Sym->isVariable())
3334 Expr = Sym->getVariableValue();
3337 if (Expr->getKind() == MCExpr::SymbolRef) {
3338 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3339 StringRef DefSymbol = Ref->getSymbol().getName();
3340 if (DefSymbol.startswith("$")) {
3341 OperandMatchResultTy ResTy =
3342 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3343 if (ResTy == MatchOperand_Success) {
3346 } else if (ResTy == MatchOperand_ParseFail)
3347 llvm_unreachable("Should never ParseFail");
3350 } else if (Expr->getKind() == MCExpr::Constant) {
3352 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3354 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3361 MipsAsmParser::OperandMatchResultTy
3362 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3363 StringRef Identifier,
3365 int Index = matchCPURegisterName(Identifier);
3367 Operands.push_back(MipsOperand::createGPRReg(
3368 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3369 return MatchOperand_Success;
3372 Index = matchHWRegsRegisterName(Identifier);
3374 Operands.push_back(MipsOperand::createHWRegsReg(
3375 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3376 return MatchOperand_Success;
3379 Index = matchFPURegisterName(Identifier);
3381 Operands.push_back(MipsOperand::createFGRReg(
3382 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3383 return MatchOperand_Success;
3386 Index = matchFCCRegisterName(Identifier);
3388 Operands.push_back(MipsOperand::createFCCReg(
3389 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3390 return MatchOperand_Success;
3393 Index = matchACRegisterName(Identifier);
3395 Operands.push_back(MipsOperand::createACCReg(
3396 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3397 return MatchOperand_Success;
3400 Index = matchMSA128RegisterName(Identifier);
3402 Operands.push_back(MipsOperand::createMSA128Reg(
3403 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3404 return MatchOperand_Success;
3407 Index = matchMSA128CtrlRegisterName(Identifier);
3409 Operands.push_back(MipsOperand::createMSACtrlReg(
3410 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3411 return MatchOperand_Success;
3414 return MatchOperand_NoMatch;
3417 MipsAsmParser::OperandMatchResultTy
3418 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3419 MCAsmParser &Parser = getParser();
3420 auto Token = Parser.getLexer().peekTok(false);
3422 if (Token.is(AsmToken::Identifier)) {
3423 DEBUG(dbgs() << ".. identifier\n");
3424 StringRef Identifier = Token.getIdentifier();
3425 OperandMatchResultTy ResTy =
3426 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3428 } else if (Token.is(AsmToken::Integer)) {
3429 DEBUG(dbgs() << ".. integer\n");
3430 Operands.push_back(MipsOperand::createNumericReg(
3431 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3433 return MatchOperand_Success;
3436 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3438 return MatchOperand_NoMatch;
3441 MipsAsmParser::OperandMatchResultTy
3442 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3443 MCAsmParser &Parser = getParser();
3444 DEBUG(dbgs() << "parseAnyRegister\n");
3446 auto Token = Parser.getTok();
3448 SMLoc S = Token.getLoc();
3450 if (Token.isNot(AsmToken::Dollar)) {
3451 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3452 if (Token.is(AsmToken::Identifier)) {
3453 if (searchSymbolAlias(Operands))
3454 return MatchOperand_Success;
3456 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3457 return MatchOperand_NoMatch;
3459 DEBUG(dbgs() << ".. $\n");
3461 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3462 if (ResTy == MatchOperand_Success) {
3464 Parser.Lex(); // identifier
3469 MipsAsmParser::OperandMatchResultTy
3470 MipsAsmParser::parseImm(OperandVector &Operands) {
3471 MCAsmParser &Parser = getParser();
3472 switch (getLexer().getKind()) {
3474 return MatchOperand_NoMatch;
3475 case AsmToken::LParen:
3476 case AsmToken::Minus:
3477 case AsmToken::Plus:
3478 case AsmToken::Integer:
3479 case AsmToken::Tilde:
3480 case AsmToken::String:
3484 const MCExpr *IdVal;
3485 SMLoc S = Parser.getTok().getLoc();
3486 if (getParser().parseExpression(IdVal))
3487 return MatchOperand_ParseFail;
3489 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3490 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3491 return MatchOperand_Success;
3494 MipsAsmParser::OperandMatchResultTy
3495 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3496 MCAsmParser &Parser = getParser();
3497 DEBUG(dbgs() << "parseJumpTarget\n");
3499 SMLoc S = getLexer().getLoc();
3501 // Integers and expressions are acceptable
3502 OperandMatchResultTy ResTy = parseImm(Operands);
3503 if (ResTy != MatchOperand_NoMatch)
3506 // Registers are a valid target and have priority over symbols.
3507 ResTy = parseAnyRegister(Operands);
3508 if (ResTy != MatchOperand_NoMatch)
3511 const MCExpr *Expr = nullptr;
3512 if (Parser.parseExpression(Expr)) {
3513 // We have no way of knowing if a symbol was consumed so we must ParseFail
3514 return MatchOperand_ParseFail;
3517 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3518 return MatchOperand_Success;
3521 MipsAsmParser::OperandMatchResultTy
3522 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3523 MCAsmParser &Parser = getParser();
3524 const MCExpr *IdVal;
3525 // If the first token is '$' we may have register operand.
3526 if (Parser.getTok().is(AsmToken::Dollar))
3527 return MatchOperand_NoMatch;
3528 SMLoc S = Parser.getTok().getLoc();
3529 if (getParser().parseExpression(IdVal))
3530 return MatchOperand_ParseFail;
3531 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3532 assert(MCE && "Unexpected MCExpr type.");
3533 int64_t Val = MCE->getValue();
3534 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3535 Operands.push_back(MipsOperand::CreateImm(
3536 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3537 return MatchOperand_Success;
3540 MipsAsmParser::OperandMatchResultTy
3541 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3542 MCAsmParser &Parser = getParser();
3543 switch (getLexer().getKind()) {
3545 return MatchOperand_NoMatch;
3546 case AsmToken::LParen:
3547 case AsmToken::Plus:
3548 case AsmToken::Minus:
3549 case AsmToken::Integer:
3554 SMLoc S = Parser.getTok().getLoc();
3556 if (getParser().parseExpression(Expr))
3557 return MatchOperand_ParseFail;
3560 if (!Expr->evaluateAsAbsolute(Val)) {
3561 Error(S, "expected immediate value");
3562 return MatchOperand_ParseFail;
3565 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3566 // and because the CPU always adds one to the immediate field, the allowed
3567 // range becomes 1..4. We'll only check the range here and will deal
3568 // with the addition/subtraction when actually decoding/encoding
3570 if (Val < 1 || Val > 4) {
3571 Error(S, "immediate not in range (1..4)");
3572 return MatchOperand_ParseFail;
3576 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3577 return MatchOperand_Success;
3580 MipsAsmParser::OperandMatchResultTy
3581 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3582 MCAsmParser &Parser = getParser();
3583 SmallVector<unsigned, 10> Regs;
3585 unsigned PrevReg = Mips::NoRegister;
3586 bool RegRange = false;
3587 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3589 if (Parser.getTok().isNot(AsmToken::Dollar))
3590 return MatchOperand_ParseFail;
3592 SMLoc S = Parser.getTok().getLoc();
3593 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3594 SMLoc E = getLexer().getLoc();
3595 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3596 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3598 // Remove last register operand because registers from register range
3599 // should be inserted first.
3600 if (RegNo == Mips::RA) {
3601 Regs.push_back(RegNo);
3603 unsigned TmpReg = PrevReg + 1;
3604 while (TmpReg <= RegNo) {
3605 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3606 Error(E, "invalid register operand");
3607 return MatchOperand_ParseFail;
3611 Regs.push_back(TmpReg++);
3617 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3618 (RegNo != Mips::RA)) {
3619 Error(E, "$16 or $31 expected");
3620 return MatchOperand_ParseFail;
3621 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3622 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3623 Error(E, "invalid register operand");
3624 return MatchOperand_ParseFail;
3625 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3626 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3627 Error(E, "consecutive register numbers expected");
3628 return MatchOperand_ParseFail;
3631 Regs.push_back(RegNo);
3634 if (Parser.getTok().is(AsmToken::Minus))
3637 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3638 !Parser.getTok().isNot(AsmToken::Comma)) {
3639 Error(E, "',' or '-' expected");
3640 return MatchOperand_ParseFail;
3643 Lex(); // Consume comma or minus
3644 if (Parser.getTok().isNot(AsmToken::Dollar))
3650 SMLoc E = Parser.getTok().getLoc();
3651 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3652 parseMemOperand(Operands);
3653 return MatchOperand_Success;
3656 MipsAsmParser::OperandMatchResultTy
3657 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3658 MCAsmParser &Parser = getParser();
3660 SMLoc S = Parser.getTok().getLoc();
3661 if (parseAnyRegister(Operands) != MatchOperand_Success)
3662 return MatchOperand_ParseFail;
3664 SMLoc E = Parser.getTok().getLoc();
3665 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3666 unsigned Reg = Op.getGPR32Reg();
3667 Operands.pop_back();
3668 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3669 return MatchOperand_Success;
3672 MipsAsmParser::OperandMatchResultTy
3673 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3674 MCAsmParser &Parser = getParser();
3675 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3676 SmallVector<unsigned, 10> Regs;
3678 if (Parser.getTok().isNot(AsmToken::Dollar))
3679 return MatchOperand_ParseFail;
3681 SMLoc S = Parser.getTok().getLoc();
3683 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3684 return MatchOperand_ParseFail;
3686 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3687 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3688 Regs.push_back(RegNo);
3690 SMLoc E = Parser.getTok().getLoc();
3691 if (Parser.getTok().isNot(AsmToken::Comma)) {
3692 Error(E, "',' expected");
3693 return MatchOperand_ParseFail;
3699 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3700 return MatchOperand_ParseFail;
3702 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3703 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3704 Regs.push_back(RegNo);
3706 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3708 return MatchOperand_Success;
3711 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3713 MCSymbolRefExpr::VariantKind VK =
3714 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3715 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3716 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3717 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3718 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3719 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3720 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3721 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3722 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3723 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3724 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3725 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3726 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3727 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3728 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3729 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3730 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3731 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3732 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3733 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3734 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3735 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3736 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3737 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3738 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3739 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3740 .Default(MCSymbolRefExpr::VK_None);
3742 assert(VK != MCSymbolRefExpr::VK_None);
3747 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3749 /// ::= '(', register, ')'
3750 /// handle it before we iterate so we don't get tripped up by the lack of
3752 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3753 MCAsmParser &Parser = getParser();
3754 if (getLexer().is(AsmToken::LParen)) {
3756 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3758 if (parseOperand(Operands, Name)) {
3759 SMLoc Loc = getLexer().getLoc();
3760 Parser.eatToEndOfStatement();
3761 return Error(Loc, "unexpected token in argument list");
3763 if (Parser.getTok().isNot(AsmToken::RParen)) {
3764 SMLoc Loc = getLexer().getLoc();
3765 Parser.eatToEndOfStatement();
3766 return Error(Loc, "unexpected token, expected ')'");
3769 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3775 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3776 /// either one of these.
3777 /// ::= '[', register, ']'
3778 /// ::= '[', integer, ']'
3779 /// handle it before we iterate so we don't get tripped up by the lack of
3781 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3782 OperandVector &Operands) {
3783 MCAsmParser &Parser = getParser();
3784 if (getLexer().is(AsmToken::LBrac)) {
3786 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3788 if (parseOperand(Operands, Name)) {
3789 SMLoc Loc = getLexer().getLoc();
3790 Parser.eatToEndOfStatement();
3791 return Error(Loc, "unexpected token in argument list");
3793 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3794 SMLoc Loc = getLexer().getLoc();
3795 Parser.eatToEndOfStatement();
3796 return Error(Loc, "unexpected token, expected ']'");
3799 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3805 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3806 SMLoc NameLoc, OperandVector &Operands) {
3807 MCAsmParser &Parser = getParser();
3808 DEBUG(dbgs() << "ParseInstruction\n");
3810 // We have reached first instruction, module directive are now forbidden.
3811 getTargetStreamer().forbidModuleDirective();
3813 // Check if we have valid mnemonic
3814 if (!mnemonicIsValid(Name, 0)) {
3815 Parser.eatToEndOfStatement();
3816 return Error(NameLoc, "unknown instruction");
3818 // First operand in MCInst is instruction mnemonic.
3819 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3821 // Read the remaining operands.
3822 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3823 // Read the first operand.
3824 if (parseOperand(Operands, Name)) {
3825 SMLoc Loc = getLexer().getLoc();
3826 Parser.eatToEndOfStatement();
3827 return Error(Loc, "unexpected token in argument list");
3829 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3831 // AFAIK, parenthesis suffixes are never on the first operand
3833 while (getLexer().is(AsmToken::Comma)) {
3834 Parser.Lex(); // Eat the comma.
3835 // Parse and remember the operand.
3836 if (parseOperand(Operands, Name)) {
3837 SMLoc Loc = getLexer().getLoc();
3838 Parser.eatToEndOfStatement();
3839 return Error(Loc, "unexpected token in argument list");
3841 // Parse bracket and parenthesis suffixes before we iterate
3842 if (getLexer().is(AsmToken::LBrac)) {
3843 if (parseBracketSuffix(Name, Operands))
3845 } else if (getLexer().is(AsmToken::LParen) &&
3846 parseParenSuffix(Name, Operands))
3850 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3851 SMLoc Loc = getLexer().getLoc();
3852 Parser.eatToEndOfStatement();
3853 return Error(Loc, "unexpected token in argument list");
3855 Parser.Lex(); // Consume the EndOfStatement.
3859 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3860 MCAsmParser &Parser = getParser();
3861 SMLoc Loc = getLexer().getLoc();
3862 Parser.eatToEndOfStatement();
3863 return Error(Loc, ErrorMsg);
3866 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3867 return Error(Loc, ErrorMsg);
3870 bool MipsAsmParser::parseSetNoAtDirective() {
3871 MCAsmParser &Parser = getParser();
3872 // Line should look like: ".set noat".
3874 // Set the $at register to $0.
3875 AssemblerOptions.back()->setATRegIndex(0);
3877 Parser.Lex(); // Eat "noat".
3879 // If this is not the end of the statement, report an error.
3880 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3881 reportParseError("unexpected token, expected end of statement");
3885 getTargetStreamer().emitDirectiveSetNoAt();
3886 Parser.Lex(); // Consume the EndOfStatement.
3890 bool MipsAsmParser::parseSetAtDirective() {
3891 // Line can be: ".set at", which sets $at to $1
3892 // or ".set at=$reg", which sets $at to $reg.
3893 MCAsmParser &Parser = getParser();
3894 Parser.Lex(); // Eat "at".
3896 if (getLexer().is(AsmToken::EndOfStatement)) {
3897 // No register was specified, so we set $at to $1.
3898 AssemblerOptions.back()->setATRegIndex(1);
3900 getTargetStreamer().emitDirectiveSetAt();
3901 Parser.Lex(); // Consume the EndOfStatement.
3905 if (getLexer().isNot(AsmToken::Equal)) {
3906 reportParseError("unexpected token, expected equals sign");
3909 Parser.Lex(); // Eat "=".
3911 if (getLexer().isNot(AsmToken::Dollar)) {
3912 if (getLexer().is(AsmToken::EndOfStatement)) {
3913 reportParseError("no register specified");
3916 reportParseError("unexpected token, expected dollar sign '$'");
3920 Parser.Lex(); // Eat "$".
3922 // Find out what "reg" is.
3924 const AsmToken &Reg = Parser.getTok();
3925 if (Reg.is(AsmToken::Identifier)) {
3926 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3927 } else if (Reg.is(AsmToken::Integer)) {
3928 AtRegNo = Reg.getIntVal();
3930 reportParseError("unexpected token, expected identifier or integer");
3934 // Check if $reg is a valid register. If it is, set $at to $reg.
3935 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3936 reportParseError("invalid register");
3939 Parser.Lex(); // Eat "reg".
3941 // If this is not the end of the statement, report an error.
3942 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3943 reportParseError("unexpected token, expected end of statement");
3947 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3949 Parser.Lex(); // Consume the EndOfStatement.
3953 bool MipsAsmParser::parseSetReorderDirective() {
3954 MCAsmParser &Parser = getParser();
3956 // If this is not the end of the statement, report an error.
3957 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3958 reportParseError("unexpected token, expected end of statement");
3961 AssemblerOptions.back()->setReorder();
3962 getTargetStreamer().emitDirectiveSetReorder();
3963 Parser.Lex(); // Consume the EndOfStatement.
3967 bool MipsAsmParser::parseSetNoReorderDirective() {
3968 MCAsmParser &Parser = getParser();
3970 // If this is not the end of the statement, report an error.
3971 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3972 reportParseError("unexpected token, expected end of statement");
3975 AssemblerOptions.back()->setNoReorder();
3976 getTargetStreamer().emitDirectiveSetNoReorder();
3977 Parser.Lex(); // Consume the EndOfStatement.
3981 bool MipsAsmParser::parseSetMacroDirective() {
3982 MCAsmParser &Parser = getParser();
3984 // If this is not the end of the statement, report an error.
3985 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3986 reportParseError("unexpected token, expected end of statement");
3989 AssemblerOptions.back()->setMacro();
3990 getTargetStreamer().emitDirectiveSetMacro();
3991 Parser.Lex(); // Consume the EndOfStatement.
3995 bool MipsAsmParser::parseSetNoMacroDirective() {
3996 MCAsmParser &Parser = getParser();
3998 // If this is not the end of the statement, report an error.
3999 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4000 reportParseError("unexpected token, expected end of statement");
4003 if (AssemblerOptions.back()->isReorder()) {
4004 reportParseError("`noreorder' must be set before `nomacro'");
4007 AssemblerOptions.back()->setNoMacro();
4008 getTargetStreamer().emitDirectiveSetNoMacro();
4009 Parser.Lex(); // Consume the EndOfStatement.
4013 bool MipsAsmParser::parseSetMsaDirective() {
4014 MCAsmParser &Parser = getParser();
4017 // If this is not the end of the statement, report an error.
4018 if (getLexer().isNot(AsmToken::EndOfStatement))
4019 return reportParseError("unexpected token, expected end of statement");
4021 setFeatureBits(Mips::FeatureMSA, "msa");
4022 getTargetStreamer().emitDirectiveSetMsa();
4026 bool MipsAsmParser::parseSetNoMsaDirective() {
4027 MCAsmParser &Parser = getParser();
4030 // If this is not the end of the statement, report an error.
4031 if (getLexer().isNot(AsmToken::EndOfStatement))
4032 return reportParseError("unexpected token, expected end of statement");
4034 clearFeatureBits(Mips::FeatureMSA, "msa");
4035 getTargetStreamer().emitDirectiveSetNoMsa();
4039 bool MipsAsmParser::parseSetNoDspDirective() {
4040 MCAsmParser &Parser = getParser();
4041 Parser.Lex(); // Eat "nodsp".
4043 // If this is not the end of the statement, report an error.
4044 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4045 reportParseError("unexpected token, expected end of statement");
4049 clearFeatureBits(Mips::FeatureDSP, "dsp");
4050 getTargetStreamer().emitDirectiveSetNoDsp();
4054 bool MipsAsmParser::parseSetMips16Directive() {
4055 MCAsmParser &Parser = getParser();
4056 Parser.Lex(); // Eat "mips16".
4058 // If this is not the end of the statement, report an error.
4059 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4060 reportParseError("unexpected token, expected end of statement");
4064 setFeatureBits(Mips::FeatureMips16, "mips16");
4065 getTargetStreamer().emitDirectiveSetMips16();
4066 Parser.Lex(); // Consume the EndOfStatement.
4070 bool MipsAsmParser::parseSetNoMips16Directive() {
4071 MCAsmParser &Parser = getParser();
4072 Parser.Lex(); // Eat "nomips16".
4074 // If this is not the end of the statement, report an error.
4075 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4076 reportParseError("unexpected token, expected end of statement");
4080 clearFeatureBits(Mips::FeatureMips16, "mips16");
4081 getTargetStreamer().emitDirectiveSetNoMips16();
4082 Parser.Lex(); // Consume the EndOfStatement.
4086 bool MipsAsmParser::parseSetFpDirective() {
4087 MCAsmParser &Parser = getParser();
4088 MipsABIFlagsSection::FpABIKind FpAbiVal;
4089 // Line can be: .set fp=32
4092 Parser.Lex(); // Eat fp token
4093 AsmToken Tok = Parser.getTok();
4094 if (Tok.isNot(AsmToken::Equal)) {
4095 reportParseError("unexpected token, expected equals sign '='");
4098 Parser.Lex(); // Eat '=' token.
4099 Tok = Parser.getTok();
4101 if (!parseFpABIValue(FpAbiVal, ".set"))
4104 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4105 reportParseError("unexpected token, expected end of statement");
4108 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4109 Parser.Lex(); // Consume the EndOfStatement.
4113 bool MipsAsmParser::parseSetOddSPRegDirective() {
4114 MCAsmParser &Parser = getParser();
4116 Parser.Lex(); // Eat "oddspreg".
4117 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4118 reportParseError("unexpected token, expected end of statement");
4122 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4123 getTargetStreamer().emitDirectiveSetOddSPReg();
4127 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4128 MCAsmParser &Parser = getParser();
4130 Parser.Lex(); // Eat "nooddspreg".
4131 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4132 reportParseError("unexpected token, expected end of statement");
4136 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4137 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4141 bool MipsAsmParser::parseSetPopDirective() {
4142 MCAsmParser &Parser = getParser();
4143 SMLoc Loc = getLexer().getLoc();
4146 if (getLexer().isNot(AsmToken::EndOfStatement))
4147 return reportParseError("unexpected token, expected end of statement");
4149 // Always keep an element on the options "stack" to prevent the user
4150 // from changing the initial options. This is how we remember them.
4151 if (AssemblerOptions.size() == 2)
4152 return reportParseError(Loc, ".set pop with no .set push");
4154 AssemblerOptions.pop_back();
4155 setAvailableFeatures(
4156 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4157 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4159 getTargetStreamer().emitDirectiveSetPop();
4163 bool MipsAsmParser::parseSetPushDirective() {
4164 MCAsmParser &Parser = getParser();
4166 if (getLexer().isNot(AsmToken::EndOfStatement))
4167 return reportParseError("unexpected token, expected end of statement");
4169 // Create a copy of the current assembler options environment and push it.
4170 AssemblerOptions.push_back(
4171 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4173 getTargetStreamer().emitDirectiveSetPush();
4177 bool MipsAsmParser::parseSetSoftFloatDirective() {
4178 MCAsmParser &Parser = getParser();
4180 if (getLexer().isNot(AsmToken::EndOfStatement))
4181 return reportParseError("unexpected token, expected end of statement");
4183 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4184 getTargetStreamer().emitDirectiveSetSoftFloat();
4188 bool MipsAsmParser::parseSetHardFloatDirective() {
4189 MCAsmParser &Parser = getParser();
4191 if (getLexer().isNot(AsmToken::EndOfStatement))
4192 return reportParseError("unexpected token, expected end of statement");
4194 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4195 getTargetStreamer().emitDirectiveSetHardFloat();
4199 bool MipsAsmParser::parseSetAssignment() {
4201 const MCExpr *Value;
4202 MCAsmParser &Parser = getParser();
4204 if (Parser.parseIdentifier(Name))
4205 reportParseError("expected identifier after .set");
4207 if (getLexer().isNot(AsmToken::Comma))
4208 return reportParseError("unexpected token, expected comma");
4211 if (Parser.parseExpression(Value))
4212 return reportParseError("expected valid expression after comma");
4214 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4215 Sym->setVariableValue(Value);
4220 bool MipsAsmParser::parseSetMips0Directive() {
4221 MCAsmParser &Parser = getParser();
4223 if (getLexer().isNot(AsmToken::EndOfStatement))
4224 return reportParseError("unexpected token, expected end of statement");
4226 // Reset assembler options to their initial values.
4227 setAvailableFeatures(
4228 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4229 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4230 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4232 getTargetStreamer().emitDirectiveSetMips0();
4236 bool MipsAsmParser::parseSetArchDirective() {
4237 MCAsmParser &Parser = getParser();
4239 if (getLexer().isNot(AsmToken::Equal))
4240 return reportParseError("unexpected token, expected equals sign");
4244 if (Parser.parseIdentifier(Arch))
4245 return reportParseError("expected arch identifier");
4247 StringRef ArchFeatureName =
4248 StringSwitch<StringRef>(Arch)
4249 .Case("mips1", "mips1")
4250 .Case("mips2", "mips2")
4251 .Case("mips3", "mips3")
4252 .Case("mips4", "mips4")
4253 .Case("mips5", "mips5")
4254 .Case("mips32", "mips32")
4255 .Case("mips32r2", "mips32r2")
4256 .Case("mips32r3", "mips32r3")
4257 .Case("mips32r5", "mips32r5")
4258 .Case("mips32r6", "mips32r6")
4259 .Case("mips64", "mips64")
4260 .Case("mips64r2", "mips64r2")
4261 .Case("mips64r3", "mips64r3")
4262 .Case("mips64r5", "mips64r5")
4263 .Case("mips64r6", "mips64r6")
4264 .Case("cnmips", "cnmips")
4265 .Case("r4000", "mips3") // This is an implementation of Mips3.
4268 if (ArchFeatureName.empty())
4269 return reportParseError("unsupported architecture");
4271 selectArch(ArchFeatureName);
4272 getTargetStreamer().emitDirectiveSetArch(Arch);
4276 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4277 MCAsmParser &Parser = getParser();
4279 if (getLexer().isNot(AsmToken::EndOfStatement))
4280 return reportParseError("unexpected token, expected end of statement");
4284 llvm_unreachable("Unimplemented feature");
4285 case Mips::FeatureDSP:
4286 setFeatureBits(Mips::FeatureDSP, "dsp");
4287 getTargetStreamer().emitDirectiveSetDsp();
4289 case Mips::FeatureMicroMips:
4290 getTargetStreamer().emitDirectiveSetMicroMips();
4292 case Mips::FeatureMips1:
4293 selectArch("mips1");
4294 getTargetStreamer().emitDirectiveSetMips1();
4296 case Mips::FeatureMips2:
4297 selectArch("mips2");
4298 getTargetStreamer().emitDirectiveSetMips2();
4300 case Mips::FeatureMips3:
4301 selectArch("mips3");
4302 getTargetStreamer().emitDirectiveSetMips3();
4304 case Mips::FeatureMips4:
4305 selectArch("mips4");
4306 getTargetStreamer().emitDirectiveSetMips4();
4308 case Mips::FeatureMips5:
4309 selectArch("mips5");
4310 getTargetStreamer().emitDirectiveSetMips5();
4312 case Mips::FeatureMips32:
4313 selectArch("mips32");
4314 getTargetStreamer().emitDirectiveSetMips32();
4316 case Mips::FeatureMips32r2:
4317 selectArch("mips32r2");
4318 getTargetStreamer().emitDirectiveSetMips32R2();
4320 case Mips::FeatureMips32r3:
4321 selectArch("mips32r3");
4322 getTargetStreamer().emitDirectiveSetMips32R3();
4324 case Mips::FeatureMips32r5:
4325 selectArch("mips32r5");
4326 getTargetStreamer().emitDirectiveSetMips32R5();
4328 case Mips::FeatureMips32r6:
4329 selectArch("mips32r6");
4330 getTargetStreamer().emitDirectiveSetMips32R6();
4332 case Mips::FeatureMips64:
4333 selectArch("mips64");
4334 getTargetStreamer().emitDirectiveSetMips64();
4336 case Mips::FeatureMips64r2:
4337 selectArch("mips64r2");
4338 getTargetStreamer().emitDirectiveSetMips64R2();
4340 case Mips::FeatureMips64r3:
4341 selectArch("mips64r3");
4342 getTargetStreamer().emitDirectiveSetMips64R3();
4344 case Mips::FeatureMips64r5:
4345 selectArch("mips64r5");
4346 getTargetStreamer().emitDirectiveSetMips64R5();
4348 case Mips::FeatureMips64r6:
4349 selectArch("mips64r6");
4350 getTargetStreamer().emitDirectiveSetMips64R6();
4356 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4357 MCAsmParser &Parser = getParser();
4358 if (getLexer().isNot(AsmToken::Comma)) {
4359 SMLoc Loc = getLexer().getLoc();
4360 Parser.eatToEndOfStatement();
4361 return Error(Loc, ErrorStr);
4364 Parser.Lex(); // Eat the comma.
4368 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4369 if (AssemblerOptions.back()->isReorder())
4370 Warning(Loc, ".cpload should be inside a noreorder section");
4372 if (inMips16Mode()) {
4373 reportParseError(".cpload is not supported in Mips16 mode");
4377 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4378 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4379 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4380 reportParseError("expected register containing function address");
4384 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4385 if (!RegOpnd.isGPRAsmReg()) {
4386 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4390 // If this is not the end of the statement, report an error.
4391 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4392 reportParseError("unexpected token, expected end of statement");
4396 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4400 bool MipsAsmParser::parseDirectiveCPSetup() {
4401 MCAsmParser &Parser = getParser();
4404 bool SaveIsReg = true;
4406 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4407 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4408 if (ResTy == MatchOperand_NoMatch) {
4409 reportParseError("expected register containing function address");
4410 Parser.eatToEndOfStatement();
4414 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4415 if (!FuncRegOpnd.isGPRAsmReg()) {
4416 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4417 Parser.eatToEndOfStatement();
4421 FuncReg = FuncRegOpnd.getGPR32Reg();
4424 if (!eatComma("unexpected token, expected comma"))
4427 ResTy = parseAnyRegister(TmpReg);
4428 if (ResTy == MatchOperand_NoMatch) {
4429 const AsmToken &Tok = Parser.getTok();
4430 if (Tok.is(AsmToken::Integer)) {
4431 Save = Tok.getIntVal();
4435 reportParseError("expected save register or stack offset");
4436 Parser.eatToEndOfStatement();
4440 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4441 if (!SaveOpnd.isGPRAsmReg()) {
4442 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4443 Parser.eatToEndOfStatement();
4446 Save = SaveOpnd.getGPR32Reg();
4449 if (!eatComma("unexpected token, expected comma"))
4453 if (Parser.parseExpression(Expr)) {
4454 reportParseError("expected expression");
4458 if (Expr->getKind() != MCExpr::SymbolRef) {
4459 reportParseError("expected symbol");
4462 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4464 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4469 bool MipsAsmParser::parseDirectiveNaN() {
4470 MCAsmParser &Parser = getParser();
4471 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4472 const AsmToken &Tok = Parser.getTok();
4474 if (Tok.getString() == "2008") {
4476 getTargetStreamer().emitDirectiveNaN2008();
4478 } else if (Tok.getString() == "legacy") {
4480 getTargetStreamer().emitDirectiveNaNLegacy();
4484 // If we don't recognize the option passed to the .nan
4485 // directive (e.g. no option or unknown option), emit an error.
4486 reportParseError("invalid option in .nan directive");
4490 bool MipsAsmParser::parseDirectiveSet() {
4491 MCAsmParser &Parser = getParser();
4492 // Get the next token.
4493 const AsmToken &Tok = Parser.getTok();
4495 if (Tok.getString() == "noat") {
4496 return parseSetNoAtDirective();
4497 } else if (Tok.getString() == "at") {
4498 return parseSetAtDirective();
4499 } else if (Tok.getString() == "arch") {
4500 return parseSetArchDirective();
4501 } else if (Tok.getString() == "fp") {
4502 return parseSetFpDirective();
4503 } else if (Tok.getString() == "oddspreg") {
4504 return parseSetOddSPRegDirective();
4505 } else if (Tok.getString() == "nooddspreg") {
4506 return parseSetNoOddSPRegDirective();
4507 } else if (Tok.getString() == "pop") {
4508 return parseSetPopDirective();
4509 } else if (Tok.getString() == "push") {
4510 return parseSetPushDirective();
4511 } else if (Tok.getString() == "reorder") {
4512 return parseSetReorderDirective();
4513 } else if (Tok.getString() == "noreorder") {
4514 return parseSetNoReorderDirective();
4515 } else if (Tok.getString() == "macro") {
4516 return parseSetMacroDirective();
4517 } else if (Tok.getString() == "nomacro") {
4518 return parseSetNoMacroDirective();
4519 } else if (Tok.getString() == "mips16") {
4520 return parseSetMips16Directive();
4521 } else if (Tok.getString() == "nomips16") {
4522 return parseSetNoMips16Directive();
4523 } else if (Tok.getString() == "nomicromips") {
4524 getTargetStreamer().emitDirectiveSetNoMicroMips();
4525 Parser.eatToEndOfStatement();
4527 } else if (Tok.getString() == "micromips") {
4528 return parseSetFeature(Mips::FeatureMicroMips);
4529 } else if (Tok.getString() == "mips0") {
4530 return parseSetMips0Directive();
4531 } else if (Tok.getString() == "mips1") {
4532 return parseSetFeature(Mips::FeatureMips1);
4533 } else if (Tok.getString() == "mips2") {
4534 return parseSetFeature(Mips::FeatureMips2);
4535 } else if (Tok.getString() == "mips3") {
4536 return parseSetFeature(Mips::FeatureMips3);
4537 } else if (Tok.getString() == "mips4") {
4538 return parseSetFeature(Mips::FeatureMips4);
4539 } else if (Tok.getString() == "mips5") {
4540 return parseSetFeature(Mips::FeatureMips5);
4541 } else if (Tok.getString() == "mips32") {
4542 return parseSetFeature(Mips::FeatureMips32);
4543 } else if (Tok.getString() == "mips32r2") {
4544 return parseSetFeature(Mips::FeatureMips32r2);
4545 } else if (Tok.getString() == "mips32r3") {
4546 return parseSetFeature(Mips::FeatureMips32r3);
4547 } else if (Tok.getString() == "mips32r5") {
4548 return parseSetFeature(Mips::FeatureMips32r5);
4549 } else if (Tok.getString() == "mips32r6") {
4550 return parseSetFeature(Mips::FeatureMips32r6);
4551 } else if (Tok.getString() == "mips64") {
4552 return parseSetFeature(Mips::FeatureMips64);
4553 } else if (Tok.getString() == "mips64r2") {
4554 return parseSetFeature(Mips::FeatureMips64r2);
4555 } else if (Tok.getString() == "mips64r3") {
4556 return parseSetFeature(Mips::FeatureMips64r3);
4557 } else if (Tok.getString() == "mips64r5") {
4558 return parseSetFeature(Mips::FeatureMips64r5);
4559 } else if (Tok.getString() == "mips64r6") {
4560 return parseSetFeature(Mips::FeatureMips64r6);
4561 } else if (Tok.getString() == "dsp") {
4562 return parseSetFeature(Mips::FeatureDSP);
4563 } else if (Tok.getString() == "nodsp") {
4564 return parseSetNoDspDirective();
4565 } else if (Tok.getString() == "msa") {
4566 return parseSetMsaDirective();
4567 } else if (Tok.getString() == "nomsa") {
4568 return parseSetNoMsaDirective();
4569 } else if (Tok.getString() == "softfloat") {
4570 return parseSetSoftFloatDirective();
4571 } else if (Tok.getString() == "hardfloat") {
4572 return parseSetHardFloatDirective();
4574 // It is just an identifier, look for an assignment.
4575 parseSetAssignment();
4582 /// parseDataDirective
4583 /// ::= .word [ expression (, expression)* ]
4584 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4585 MCAsmParser &Parser = getParser();
4586 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4588 const MCExpr *Value;
4589 if (getParser().parseExpression(Value))
4592 getParser().getStreamer().EmitValue(Value, Size);
4594 if (getLexer().is(AsmToken::EndOfStatement))
4597 if (getLexer().isNot(AsmToken::Comma))
4598 return Error(L, "unexpected token, expected comma");
4607 /// parseDirectiveGpWord
4608 /// ::= .gpword local_sym
4609 bool MipsAsmParser::parseDirectiveGpWord() {
4610 MCAsmParser &Parser = getParser();
4611 const MCExpr *Value;
4612 // EmitGPRel32Value requires an expression, so we are using base class
4613 // method to evaluate the expression.
4614 if (getParser().parseExpression(Value))
4616 getParser().getStreamer().EmitGPRel32Value(Value);
4618 if (getLexer().isNot(AsmToken::EndOfStatement))
4619 return Error(getLexer().getLoc(),
4620 "unexpected token, expected end of statement");
4621 Parser.Lex(); // Eat EndOfStatement token.
4625 /// parseDirectiveGpDWord
4626 /// ::= .gpdword local_sym
4627 bool MipsAsmParser::parseDirectiveGpDWord() {
4628 MCAsmParser &Parser = getParser();
4629 const MCExpr *Value;
4630 // EmitGPRel64Value requires an expression, so we are using base class
4631 // method to evaluate the expression.
4632 if (getParser().parseExpression(Value))
4634 getParser().getStreamer().EmitGPRel64Value(Value);
4636 if (getLexer().isNot(AsmToken::EndOfStatement))
4637 return Error(getLexer().getLoc(),
4638 "unexpected token, expected end of statement");
4639 Parser.Lex(); // Eat EndOfStatement token.
4643 bool MipsAsmParser::parseDirectiveOption() {
4644 MCAsmParser &Parser = getParser();
4645 // Get the option token.
4646 AsmToken Tok = Parser.getTok();
4647 // At the moment only identifiers are supported.
4648 if (Tok.isNot(AsmToken::Identifier)) {
4649 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4650 Parser.eatToEndOfStatement();
4654 StringRef Option = Tok.getIdentifier();
4656 if (Option == "pic0") {
4657 getTargetStreamer().emitDirectiveOptionPic0();
4659 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4660 Error(Parser.getTok().getLoc(),
4661 "unexpected token, expected end of statement");
4662 Parser.eatToEndOfStatement();
4667 if (Option == "pic2") {
4668 getTargetStreamer().emitDirectiveOptionPic2();
4670 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4671 Error(Parser.getTok().getLoc(),
4672 "unexpected token, expected end of statement");
4673 Parser.eatToEndOfStatement();
4679 Warning(Parser.getTok().getLoc(),
4680 "unknown option, expected 'pic0' or 'pic2'");
4681 Parser.eatToEndOfStatement();
4685 /// parseInsnDirective
4687 bool MipsAsmParser::parseInsnDirective() {
4688 // If this is not the end of the statement, report an error.
4689 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4690 reportParseError("unexpected token, expected end of statement");
4694 // The actual label marking happens in
4695 // MipsELFStreamer::createPendingLabelRelocs().
4696 getTargetStreamer().emitDirectiveInsn();
4698 getParser().Lex(); // Eat EndOfStatement token.
4702 /// parseDirectiveModule
4703 /// ::= .module oddspreg
4704 /// ::= .module nooddspreg
4705 /// ::= .module fp=value
4706 /// ::= .module softfloat
4707 /// ::= .module hardfloat
4708 bool MipsAsmParser::parseDirectiveModule() {
4709 MCAsmParser &Parser = getParser();
4710 MCAsmLexer &Lexer = getLexer();
4711 SMLoc L = Lexer.getLoc();
4713 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4714 // TODO : get a better message.
4715 reportParseError(".module directive must appear before any code");
4720 if (Parser.parseIdentifier(Option)) {
4721 reportParseError("expected .module option identifier");
4725 if (Option == "oddspreg") {
4726 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4728 // Synchronize the abiflags information with the FeatureBits information we
4730 getTargetStreamer().updateABIInfo(*this);
4732 // If printing assembly, use the recently updated abiflags information.
4733 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4734 // emitted at the end).
4735 getTargetStreamer().emitDirectiveModuleOddSPReg();
4737 // If this is not the end of the statement, report an error.
4738 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4739 reportParseError("unexpected token, expected end of statement");
4743 return false; // parseDirectiveModule has finished successfully.
4744 } else if (Option == "nooddspreg") {
4746 Error(L, "'.module nooddspreg' requires the O32 ABI");
4750 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4752 // Synchronize the abiflags information with the FeatureBits information we
4754 getTargetStreamer().updateABIInfo(*this);
4756 // If printing assembly, use the recently updated abiflags information.
4757 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4758 // emitted at the end).
4759 getTargetStreamer().emitDirectiveModuleOddSPReg();
4761 // If this is not the end of the statement, report an error.
4762 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4763 reportParseError("unexpected token, expected end of statement");
4767 return false; // parseDirectiveModule has finished successfully.
4768 } else if (Option == "fp") {
4769 return parseDirectiveModuleFP();
4770 } else if (Option == "softfloat") {
4771 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4773 // Synchronize the ABI Flags information with the FeatureBits information we
4775 getTargetStreamer().updateABIInfo(*this);
4777 // If printing assembly, use the recently updated ABI Flags information.
4778 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4780 getTargetStreamer().emitDirectiveModuleSoftFloat();
4782 // If this is not the end of the statement, report an error.
4783 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4784 reportParseError("unexpected token, expected end of statement");
4788 return false; // parseDirectiveModule has finished successfully.
4789 } else if (Option == "hardfloat") {
4790 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4792 // Synchronize the ABI Flags information with the FeatureBits information we
4794 getTargetStreamer().updateABIInfo(*this);
4796 // If printing assembly, use the recently updated ABI Flags information.
4797 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4799 getTargetStreamer().emitDirectiveModuleHardFloat();
4801 // If this is not the end of the statement, report an error.
4802 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4803 reportParseError("unexpected token, expected end of statement");
4807 return false; // parseDirectiveModule has finished successfully.
4809 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4813 /// parseDirectiveModuleFP
4817 bool MipsAsmParser::parseDirectiveModuleFP() {
4818 MCAsmParser &Parser = getParser();
4819 MCAsmLexer &Lexer = getLexer();
4821 if (Lexer.isNot(AsmToken::Equal)) {
4822 reportParseError("unexpected token, expected equals sign '='");
4825 Parser.Lex(); // Eat '=' token.
4827 MipsABIFlagsSection::FpABIKind FpABI;
4828 if (!parseFpABIValue(FpABI, ".module"))
4831 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4832 reportParseError("unexpected token, expected end of statement");
4836 // Synchronize the abiflags information with the FeatureBits information we
4838 getTargetStreamer().updateABIInfo(*this);
4840 // If printing assembly, use the recently updated abiflags information.
4841 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4842 // emitted at the end).
4843 getTargetStreamer().emitDirectiveModuleFP();
4845 Parser.Lex(); // Consume the EndOfStatement.
4849 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4850 StringRef Directive) {
4851 MCAsmParser &Parser = getParser();
4852 MCAsmLexer &Lexer = getLexer();
4853 bool ModuleLevelOptions = Directive == ".module";
4855 if (Lexer.is(AsmToken::Identifier)) {
4856 StringRef Value = Parser.getTok().getString();
4859 if (Value != "xx") {
4860 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4865 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4869 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4870 if (ModuleLevelOptions) {
4871 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4872 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4874 setFeatureBits(Mips::FeatureFPXX, "fpxx");
4875 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4880 if (Lexer.is(AsmToken::Integer)) {
4881 unsigned Value = Parser.getTok().getIntVal();
4884 if (Value != 32 && Value != 64) {
4885 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4891 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4895 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4896 if (ModuleLevelOptions) {
4897 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4898 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4900 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4901 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4904 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4905 if (ModuleLevelOptions) {
4906 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4907 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4909 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4910 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
4920 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4921 MCAsmParser &Parser = getParser();
4922 StringRef IDVal = DirectiveID.getString();
4924 if (IDVal == ".cpload")
4925 return parseDirectiveCpLoad(DirectiveID.getLoc());
4926 if (IDVal == ".dword") {
4927 parseDataDirective(8, DirectiveID.getLoc());
4930 if (IDVal == ".ent") {
4931 StringRef SymbolName;
4933 if (Parser.parseIdentifier(SymbolName)) {
4934 reportParseError("expected identifier after .ent");
4938 // There's an undocumented extension that allows an integer to
4939 // follow the name of the procedure which AFAICS is ignored by GAS.
4940 // Example: .ent foo,2
4941 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4942 if (getLexer().isNot(AsmToken::Comma)) {
4943 // Even though we accept this undocumented extension for compatibility
4944 // reasons, the additional integer argument does not actually change
4945 // the behaviour of the '.ent' directive, so we would like to discourage
4946 // its use. We do this by not referring to the extended version in
4947 // error messages which are not directly related to its use.
4948 reportParseError("unexpected token, expected end of statement");
4951 Parser.Lex(); // Eat the comma.
4952 const MCExpr *DummyNumber;
4953 int64_t DummyNumberVal;
4954 // If the user was explicitly trying to use the extended version,
4955 // we still give helpful extension-related error messages.
4956 if (Parser.parseExpression(DummyNumber)) {
4957 reportParseError("expected number after comma");
4960 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4961 reportParseError("expected an absolute expression after comma");
4966 // If this is not the end of the statement, report an error.
4967 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4968 reportParseError("unexpected token, expected end of statement");
4972 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4974 getTargetStreamer().emitDirectiveEnt(*Sym);
4979 if (IDVal == ".end") {
4980 StringRef SymbolName;
4982 if (Parser.parseIdentifier(SymbolName)) {
4983 reportParseError("expected identifier after .end");
4987 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4988 reportParseError("unexpected token, expected end of statement");
4992 if (CurrentFn == nullptr) {
4993 reportParseError(".end used without .ent");
4997 if ((SymbolName != CurrentFn->getName())) {
4998 reportParseError(".end symbol does not match .ent symbol");
5002 getTargetStreamer().emitDirectiveEnd(SymbolName);
5003 CurrentFn = nullptr;
5007 if (IDVal == ".frame") {
5008 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5009 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5010 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5011 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5012 reportParseError("expected stack register");
5016 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5017 if (!StackRegOpnd.isGPRAsmReg()) {
5018 reportParseError(StackRegOpnd.getStartLoc(),
5019 "expected general purpose register");
5022 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5024 if (Parser.getTok().is(AsmToken::Comma))
5027 reportParseError("unexpected token, expected comma");
5031 // Parse the frame size.
5032 const MCExpr *FrameSize;
5033 int64_t FrameSizeVal;
5035 if (Parser.parseExpression(FrameSize)) {
5036 reportParseError("expected frame size value");
5040 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5041 reportParseError("frame size not an absolute expression");
5045 if (Parser.getTok().is(AsmToken::Comma))
5048 reportParseError("unexpected token, expected comma");
5052 // Parse the return register.
5054 ResTy = parseAnyRegister(TmpReg);
5055 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5056 reportParseError("expected return register");
5060 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5061 if (!ReturnRegOpnd.isGPRAsmReg()) {
5062 reportParseError(ReturnRegOpnd.getStartLoc(),
5063 "expected general purpose register");
5067 // If this is not the end of the statement, report an error.
5068 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5069 reportParseError("unexpected token, expected end of statement");
5073 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5074 ReturnRegOpnd.getGPR32Reg());
5078 if (IDVal == ".set") {
5079 return parseDirectiveSet();
5082 if (IDVal == ".mask" || IDVal == ".fmask") {
5083 // .mask bitmask, frame_offset
5084 // bitmask: One bit for each register used.
5085 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5086 // first register is expected to be saved.
5088 // .mask 0x80000000, -4
5089 // .fmask 0x80000000, -4
5092 // Parse the bitmask
5093 const MCExpr *BitMask;
5096 if (Parser.parseExpression(BitMask)) {
5097 reportParseError("expected bitmask value");
5101 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5102 reportParseError("bitmask not an absolute expression");
5106 if (Parser.getTok().is(AsmToken::Comma))
5109 reportParseError("unexpected token, expected comma");
5113 // Parse the frame_offset
5114 const MCExpr *FrameOffset;
5115 int64_t FrameOffsetVal;
5117 if (Parser.parseExpression(FrameOffset)) {
5118 reportParseError("expected frame offset value");
5122 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5123 reportParseError("frame offset not an absolute expression");
5127 // If this is not the end of the statement, report an error.
5128 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5129 reportParseError("unexpected token, expected end of statement");
5133 if (IDVal == ".mask")
5134 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5136 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5140 if (IDVal == ".nan")
5141 return parseDirectiveNaN();
5143 if (IDVal == ".gpword") {
5144 parseDirectiveGpWord();
5148 if (IDVal == ".gpdword") {
5149 parseDirectiveGpDWord();
5153 if (IDVal == ".word") {
5154 parseDataDirective(4, DirectiveID.getLoc());
5158 if (IDVal == ".option")
5159 return parseDirectiveOption();
5161 if (IDVal == ".abicalls") {
5162 getTargetStreamer().emitDirectiveAbiCalls();
5163 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5164 Error(Parser.getTok().getLoc(),
5165 "unexpected token, expected end of statement");
5167 Parser.eatToEndOfStatement();
5172 if (IDVal == ".cpsetup")
5173 return parseDirectiveCPSetup();
5175 if (IDVal == ".module")
5176 return parseDirectiveModule();
5178 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5179 return parseInternalDirectiveReallowModule();
5181 if (IDVal == ".insn")
5182 return parseInsnDirective();
5187 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5188 // If this is not the end of the statement, report an error.
5189 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5190 reportParseError("unexpected token, expected end of statement");
5194 getTargetStreamer().reallowModuleDirective();
5196 getParser().Lex(); // Eat EndOfStatement token.
5200 extern "C" void LLVMInitializeMipsAsmParser() {
5201 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5202 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5203 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5204 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5207 #define GET_REGISTER_MATCHER
5208 #define GET_MATCHER_IMPLEMENTATION
5209 #include "MipsGenAsmMatcher.inc"