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 void emitRX(unsigned Opcode, unsigned DstReg, MCOperand Imm, SMLoc IDLoc,
1731 SmallVectorImpl<MCInst> &Instructions) {
1733 tmpInst.setOpcode(Opcode);
1734 tmpInst.addOperand(MCOperand::createReg(DstReg));
1735 tmpInst.addOperand(Imm);
1736 tmpInst.setLoc(IDLoc);
1737 Instructions.push_back(tmpInst);
1740 void emitRI(unsigned Opcode, unsigned DstReg, int16_t Imm, SMLoc IDLoc,
1741 SmallVectorImpl<MCInst> &Instructions) {
1742 emitRX(Opcode, DstReg, MCOperand::createImm(Imm), IDLoc, Instructions);
1746 void emitRRX(unsigned Opcode, unsigned DstReg, unsigned SrcReg, MCOperand Imm,
1747 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1749 tmpInst.setOpcode(Opcode);
1750 tmpInst.addOperand(MCOperand::createReg(DstReg));
1751 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1752 tmpInst.addOperand(Imm);
1753 tmpInst.setLoc(IDLoc);
1754 Instructions.push_back(tmpInst);
1757 void emitRRR(unsigned Opcode, unsigned DstReg, unsigned SrcReg,
1758 unsigned SrcReg2, SMLoc IDLoc,
1759 SmallVectorImpl<MCInst> &Instructions) {
1760 emitRRX(Opcode, DstReg, SrcReg, MCOperand::createReg(SrcReg2), IDLoc,
1764 void emitRRI(unsigned Opcode, unsigned DstReg, unsigned SrcReg, int16_t Imm,
1765 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1766 emitRRX(Opcode, DstReg, SrcReg, MCOperand::createImm(Imm), IDLoc,
1770 template <int16_t ShiftAmount>
1771 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1772 SmallVectorImpl<MCInst> &Instructions) {
1773 if (ShiftAmount >= 32)
1774 emitRRI(Mips::DSLL32, RegNo, RegNo, ShiftAmount - 32, IDLoc, Instructions);
1775 else if (ShiftAmount > 0)
1776 emitRRI(Mips::DSLL, RegNo, RegNo, ShiftAmount, IDLoc, Instructions);
1778 // There's no need for an ORi if the immediate is 0.
1779 if (Operand.isImm() && Operand.getImm() == 0)
1782 emitRRX(Mips::ORi, RegNo, RegNo, Operand, IDLoc, Instructions);
1785 template <unsigned ShiftAmount>
1786 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1787 SmallVectorImpl<MCInst> &Instructions) {
1788 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1793 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1794 SmallVectorImpl<MCInst> &Instructions) {
1795 // Create a JALR instruction which is going to replace the pseudo-JAL.
1797 JalrInst.setLoc(IDLoc);
1798 const MCOperand FirstRegOp = Inst.getOperand(0);
1799 const unsigned Opcode = Inst.getOpcode();
1801 if (Opcode == Mips::JalOneReg) {
1802 // jal $rs => jalr $rs
1803 if (inMicroMipsMode()) {
1804 JalrInst.setOpcode(Mips::JALR16_MM);
1805 JalrInst.addOperand(FirstRegOp);
1807 JalrInst.setOpcode(Mips::JALR);
1808 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1809 JalrInst.addOperand(FirstRegOp);
1811 } else if (Opcode == Mips::JalTwoReg) {
1812 // jal $rd, $rs => jalr $rd, $rs
1813 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1814 JalrInst.addOperand(FirstRegOp);
1815 const MCOperand SecondRegOp = Inst.getOperand(1);
1816 JalrInst.addOperand(SecondRegOp);
1818 Instructions.push_back(JalrInst);
1820 // If .set reorder is active, emit a NOP after it.
1821 if (AssemblerOptions.back()->isReorder()) {
1822 // This is a 32-bit NOP because these 2 pseudo-instructions
1823 // do not have a short delay slot.
1825 NopInst.setOpcode(Mips::SLL);
1826 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1827 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1828 NopInst.addOperand(MCOperand::createImm(0));
1829 Instructions.push_back(NopInst);
1835 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1836 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1837 SmallVectorImpl<MCInst> &Instructions) {
1838 if (!Is32BitImm && !isGP64bit()) {
1839 Error(IDLoc, "instruction requires a 64-bit architecture");
1844 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1845 // Sign extend up to 64-bit so that the predicates match the hardware
1846 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
1848 ImmValue = SignExtend64<32>(ImmValue);
1850 Error(IDLoc, "instruction requires a 32-bit immediate");
1855 bool UseSrcReg = false;
1856 if (SrcReg != Mips::NoRegister)
1859 unsigned TmpReg = DstReg;
1860 if (UseSrcReg && (DstReg == SrcReg)) {
1861 // At this point we need AT to perform the expansions and we exit if it is
1863 unsigned ATReg = getATReg(IDLoc);
1869 // FIXME: gas has a special case for values that are 000...1111, which
1870 // becomes a li -1 and then a dsrl
1871 if (isInt<16>(ImmValue)) {
1872 // li d,j => addiu d,$zero,j
1874 SrcReg = Mips::ZERO;
1875 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
1876 } else if (isUInt<16>(ImmValue)) {
1877 // li d,j => ori d,$zero,j
1878 unsigned TmpReg = DstReg;
1879 if (SrcReg == DstReg) {
1880 unsigned ATReg = getATReg(IDLoc);
1886 emitRRI(Mips::ORi, TmpReg, Mips::ZERO, ImmValue, IDLoc, Instructions);
1888 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1889 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1890 warnIfNoMacro(IDLoc);
1892 // For all other values which are representable as a 32-bit integer:
1893 // li d,j => lui d,hi16(j)
1895 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1896 uint16_t Bits15To0 = ImmValue & 0xffff;
1898 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1899 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1901 emitRRI(Mips::ORi, TmpReg, Mips::ZERO, Bits31To16, IDLoc, Instructions);
1902 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
1904 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
1905 createLShiftOri<0>(Bits15To0, TmpReg, IDLoc, Instructions);
1908 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1910 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1911 warnIfNoMacro(IDLoc);
1913 // <------- lo32 ------>
1914 // <------- hi32 ------>
1915 // <- hi16 -> <- lo16 ->
1916 // _________________________________
1918 // | 16-bits | 16-bits | 16-bits |
1919 // |__________|__________|__________|
1921 // For any 64-bit value that is representable as a 48-bit integer:
1922 // li d,j => lui d,hi16(j)
1923 // ori d,d,hi16(lo32(j))
1925 // ori d,d,lo16(lo32(j))
1926 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1927 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1928 uint16_t Bits15To0 = ImmValue & 0xffff;
1930 emitRI(Mips::LUi, TmpReg, Bits47To32, IDLoc, Instructions);
1931 createLShiftOri<0>(Bits31To16, TmpReg, IDLoc, Instructions);
1932 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1935 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1938 warnIfNoMacro(IDLoc);
1940 // <------- hi32 ------> <------- lo32 ------>
1941 // <- hi16 -> <- lo16 ->
1942 // ___________________________________________
1944 // | 16-bits | 16-bits | 16-bits | 16-bits |
1945 // |__________|__________|__________|__________|
1947 // For all other values which are representable as a 64-bit integer:
1948 // li d,j => lui d,hi16(j)
1949 // ori d,d,lo16(hi32(j))
1951 // ori d,d,hi16(lo32(j))
1953 // ori d,d,lo16(lo32(j))
1954 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1955 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1956 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1957 uint16_t Bits15To0 = ImmValue & 0xffff;
1959 emitRI(Mips::LUi, TmpReg, Bits63To48, IDLoc, Instructions);
1960 createLShiftOri<0>(Bits47To32, TmpReg, IDLoc, Instructions);
1962 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1963 // two left shifts of 16 bits.
1964 if (Bits31To16 == 0) {
1965 createLShiftOri<32>(Bits15To0, TmpReg, IDLoc, Instructions);
1967 createLShiftOri<16>(Bits31To16, TmpReg, IDLoc, Instructions);
1968 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1972 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1977 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1978 SmallVectorImpl<MCInst> &Instructions) {
1979 const MCOperand &ImmOp = Inst.getOperand(1);
1980 assert(ImmOp.isImm() && "expected immediate operand kind");
1981 const MCOperand &DstRegOp = Inst.getOperand(0);
1982 assert(DstRegOp.isReg() && "expected register operand kind");
1984 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1985 Is32BitImm, IDLoc, Instructions))
1992 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1993 SmallVectorImpl<MCInst> &Instructions) {
1994 const MCOperand &DstRegOp = Inst.getOperand(0);
1995 assert(DstRegOp.isReg() && "expected register operand kind");
1997 const MCOperand &SrcRegOp = Inst.getOperand(1);
1998 assert(SrcRegOp.isReg() && "expected register operand kind");
2000 const MCOperand &ImmOp = Inst.getOperand(2);
2001 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
2002 "expected immediate operand kind");
2003 if (!ImmOp.isImm()) {
2004 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
2005 SrcRegOp.getReg(), Is32BitImm, IDLoc,
2012 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
2013 Is32BitImm, IDLoc, Instructions))
2020 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2021 SmallVectorImpl<MCInst> &Instructions) {
2022 const MCOperand &DstRegOp = Inst.getOperand(0);
2023 assert(DstRegOp.isReg() && "expected register operand kind");
2025 const MCOperand &ImmOp = Inst.getOperand(1);
2026 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
2027 "expected immediate operand kind");
2028 if (!ImmOp.isImm()) {
2029 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
2030 Mips::NoRegister, Is32BitImm, IDLoc,
2037 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2038 Is32BitImm, IDLoc, Instructions))
2044 bool MipsAsmParser::loadAndAddSymbolAddress(
2045 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2046 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2047 warnIfNoMacro(IDLoc);
2049 if (Is32BitSym && isABI_N64())
2050 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
2053 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2054 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2055 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2056 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2057 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2059 bool UseSrcReg = SrcReg != Mips::NoRegister;
2061 unsigned TmpReg = DstReg;
2062 if (UseSrcReg && (DstReg == SrcReg)) {
2063 // At this point we need AT to perform the expansions and we exit if it is
2065 unsigned ATReg = getATReg(IDLoc);
2072 // If it's a 64-bit architecture, expand to:
2073 // la d,sym => lui d,highest(sym)
2074 // ori d,d,higher(sym)
2076 // ori d,d,hi16(sym)
2078 // ori d,d,lo16(sym)
2079 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2080 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2081 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2082 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2084 tmpInst.setOpcode(Mips::LUi);
2085 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2086 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
2087 Instructions.push_back(tmpInst);
2089 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), TmpReg, SMLoc(),
2091 createLShiftOri<16>(MCOperand::createExpr(HiExpr), TmpReg, SMLoc(),
2093 createLShiftOri<16>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2096 // Otherwise, expand to:
2097 // la d,sym => lui d,hi16(sym)
2098 // ori d,d,lo16(sym)
2099 tmpInst.setOpcode(Mips::LUi);
2100 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2101 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2102 Instructions.push_back(tmpInst);
2104 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), SMLoc(),
2109 createAddu(DstReg, TmpReg, SrcReg, !Is32BitSym, Instructions);
2114 bool MipsAsmParser::expandUncondBranchMMPseudo(
2115 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2116 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2117 "unexpected number of operands");
2119 MCOperand Offset = Inst.getOperand(0);
2120 if (Offset.isExpr()) {
2122 Inst.setOpcode(Mips::BEQ_MM);
2123 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2124 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2125 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2127 assert(Offset.isImm() && "expected immediate operand kind");
2128 if (isIntN(11, Offset.getImm())) {
2129 // If offset fits into 11 bits then this instruction becomes microMIPS
2130 // 16-bit unconditional branch instruction.
2131 Inst.setOpcode(Mips::B16_MM);
2133 if (!isIntN(17, Offset.getImm()))
2134 Error(IDLoc, "branch target out of range");
2135 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2136 Error(IDLoc, "branch to misaligned address");
2138 Inst.setOpcode(Mips::BEQ_MM);
2139 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2140 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2141 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2144 Instructions.push_back(Inst);
2146 // If .set reorder is active, emit a NOP after the branch instruction.
2147 if (AssemblerOptions.back()->isReorder())
2148 createNop(true, IDLoc, Instructions);
2153 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2154 SmallVectorImpl<MCInst> &Instructions) {
2155 const MCOperand &DstRegOp = Inst.getOperand(0);
2156 assert(DstRegOp.isReg() && "expected register operand kind");
2158 const MCOperand &ImmOp = Inst.getOperand(1);
2159 assert(ImmOp.isImm() && "expected immediate operand kind");
2161 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2162 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2164 unsigned OpCode = 0;
2165 switch(Inst.getOpcode()) {
2173 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2177 int64_t ImmValue = ImmOp.getImm();
2178 if (ImmValue == 0) {
2180 BranchInst.setOpcode(OpCode);
2181 BranchInst.addOperand(DstRegOp);
2182 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2183 BranchInst.addOperand(MemOffsetOp);
2184 Instructions.push_back(BranchInst);
2186 warnIfNoMacro(IDLoc);
2188 unsigned ATReg = getATReg(IDLoc);
2192 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2197 BranchInst.setOpcode(OpCode);
2198 BranchInst.addOperand(DstRegOp);
2199 BranchInst.addOperand(MCOperand::createReg(ATReg));
2200 BranchInst.addOperand(MemOffsetOp);
2201 Instructions.push_back(BranchInst);
2206 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2207 SmallVectorImpl<MCInst> &Instructions,
2208 bool isLoad, bool isImmOpnd) {
2210 unsigned ImmOffset, HiOffset, LoOffset;
2211 const MCExpr *ExprOffset;
2213 // 1st operand is either the source or destination register.
2214 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2215 unsigned RegOpNum = Inst.getOperand(0).getReg();
2216 // 2nd operand is the base register.
2217 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2218 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2219 // 3rd operand is either an immediate or expression.
2221 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2222 ImmOffset = Inst.getOperand(2).getImm();
2223 LoOffset = ImmOffset & 0x0000ffff;
2224 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2225 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2226 if (LoOffset & 0x8000)
2229 ExprOffset = Inst.getOperand(2).getExpr();
2230 // All instructions will have the same location.
2231 TempInst.setLoc(IDLoc);
2232 // These are some of the types of expansions we perform here:
2233 // 1) lw $8, sym => lui $8, %hi(sym)
2234 // lw $8, %lo(sym)($8)
2235 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2237 // lw $8, %lo(offset)($9)
2238 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2240 // lw $8, %lo(offset)($at)
2241 // 4) sw $8, sym => lui $at, %hi(sym)
2242 // sw $8, %lo(sym)($at)
2243 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2245 // sw $8, %lo(offset)($at)
2246 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2247 // ldc1 $f0, %lo(sym)($at)
2249 // For load instructions we can use the destination register as a temporary
2250 // if base and dst are different (examples 1 and 2) and if the base register
2251 // is general purpose otherwise we must use $at (example 6) and error if it's
2252 // not available. For stores we must use $at (examples 4 and 5) because we
2253 // must not clobber the source register setting up the offset.
2254 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2255 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2256 unsigned RegClassIDOp0 =
2257 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2258 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2259 (RegClassIDOp0 == Mips::GPR64RegClassID);
2260 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2261 TmpRegNum = RegOpNum;
2263 // At this point we need AT to perform the expansions and we exit if it is
2265 TmpRegNum = getATReg(IDLoc);
2270 TempInst.setOpcode(Mips::LUi);
2271 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2273 TempInst.addOperand(MCOperand::createImm(HiOffset));
2275 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2276 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2278 // Add the instruction to the list.
2279 Instructions.push_back(TempInst);
2280 // Prepare TempInst for next instruction.
2282 // Add temp register to base.
2283 if (BaseRegNum != Mips::ZERO) {
2284 TempInst.setOpcode(Mips::ADDu);
2285 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2286 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2287 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2288 Instructions.push_back(TempInst);
2291 // And finally, create original instruction with low part
2292 // of offset and new base.
2293 TempInst.setOpcode(Inst.getOpcode());
2294 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2295 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2297 TempInst.addOperand(MCOperand::createImm(LoOffset));
2299 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2300 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2302 Instructions.push_back(TempInst);
2307 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2308 SmallVectorImpl<MCInst> &Instructions) {
2309 unsigned OpNum = Inst.getNumOperands();
2310 unsigned Opcode = Inst.getOpcode();
2311 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2313 assert (Inst.getOperand(OpNum - 1).isImm() &&
2314 Inst.getOperand(OpNum - 2).isReg() &&
2315 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2317 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2318 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2319 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2320 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2321 // It can be implemented as SWM16 or LWM16 instruction.
2322 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2324 Inst.setOpcode(NewOpcode);
2325 Instructions.push_back(Inst);
2329 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2330 SmallVectorImpl<MCInst> &Instructions) {
2331 unsigned PseudoOpcode = Inst.getOpcode();
2332 unsigned SrcReg = Inst.getOperand(0).getReg();
2333 unsigned TrgReg = Inst.getOperand(1).getReg();
2334 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2336 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2337 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2339 switch (PseudoOpcode) {
2342 AcceptsEquality = false;
2343 ReverseOrderSLT = false;
2344 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2345 ZeroSrcOpcode = Mips::BGTZ;
2346 ZeroTrgOpcode = Mips::BLTZ;
2350 AcceptsEquality = true;
2351 ReverseOrderSLT = true;
2352 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2353 ZeroSrcOpcode = Mips::BGEZ;
2354 ZeroTrgOpcode = Mips::BLEZ;
2358 AcceptsEquality = true;
2359 ReverseOrderSLT = false;
2360 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2361 ZeroSrcOpcode = Mips::BLEZ;
2362 ZeroTrgOpcode = Mips::BGEZ;
2366 AcceptsEquality = false;
2367 ReverseOrderSLT = true;
2368 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2369 ZeroSrcOpcode = Mips::BLTZ;
2370 ZeroTrgOpcode = Mips::BGTZ;
2373 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2377 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2378 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2379 if (IsSrcRegZero && IsTrgRegZero) {
2380 // FIXME: All of these Opcode-specific if's are needed for compatibility
2381 // with GAS' behaviour. However, they may not generate the most efficient
2382 // code in some circumstances.
2383 if (PseudoOpcode == Mips::BLT) {
2384 BranchInst.setOpcode(Mips::BLTZ);
2385 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2386 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2387 Instructions.push_back(BranchInst);
2390 if (PseudoOpcode == Mips::BLE) {
2391 BranchInst.setOpcode(Mips::BLEZ);
2392 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2393 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2394 Instructions.push_back(BranchInst);
2395 Warning(IDLoc, "branch is always taken");
2398 if (PseudoOpcode == Mips::BGE) {
2399 BranchInst.setOpcode(Mips::BGEZ);
2400 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2401 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2402 Instructions.push_back(BranchInst);
2403 Warning(IDLoc, "branch is always taken");
2406 if (PseudoOpcode == Mips::BGT) {
2407 BranchInst.setOpcode(Mips::BGTZ);
2408 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2409 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2410 Instructions.push_back(BranchInst);
2413 if (PseudoOpcode == Mips::BGTU) {
2414 BranchInst.setOpcode(Mips::BNE);
2415 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2416 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2417 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2418 Instructions.push_back(BranchInst);
2421 if (AcceptsEquality) {
2422 // If both registers are $0 and the pseudo-branch accepts equality, it
2423 // will always be taken, so we emit an unconditional branch.
2424 BranchInst.setOpcode(Mips::BEQ);
2425 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2426 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2427 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2428 Instructions.push_back(BranchInst);
2429 Warning(IDLoc, "branch is always taken");
2432 // If both registers are $0 and the pseudo-branch does not accept
2433 // equality, it will never be taken, so we don't have to emit anything.
2436 if (IsSrcRegZero || IsTrgRegZero) {
2437 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2438 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2439 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2440 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2441 // the pseudo-branch will never be taken, so we don't emit anything.
2442 // This only applies to unsigned pseudo-branches.
2445 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2446 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2447 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2448 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2449 // the pseudo-branch will always be taken, so we emit an unconditional
2451 // This only applies to unsigned pseudo-branches.
2452 BranchInst.setOpcode(Mips::BEQ);
2453 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2454 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2455 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2456 Instructions.push_back(BranchInst);
2457 Warning(IDLoc, "branch is always taken");
2461 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2462 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2463 // the pseudo-branch will be taken only when the non-zero register is
2464 // different from 0, so we emit a BNEZ.
2466 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2467 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2468 // the pseudo-branch will be taken only when the non-zero register is
2469 // equal to 0, so we emit a BEQZ.
2471 // Because only BLEU and BGEU branch on equality, we can use the
2472 // AcceptsEquality variable to decide when to emit the BEQZ.
2473 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2474 BranchInst.addOperand(
2475 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2476 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2477 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2478 Instructions.push_back(BranchInst);
2481 // If we have a signed pseudo-branch and one of the registers is $0,
2482 // we can use an appropriate compare-to-zero branch. We select which one
2483 // to use in the switch statement above.
2484 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2485 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2486 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2487 Instructions.push_back(BranchInst);
2491 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2492 // expansions. If it is not available, we return.
2493 unsigned ATRegNum = getATReg(IDLoc);
2497 warnIfNoMacro(IDLoc);
2499 // SLT fits well with 2 of our 4 pseudo-branches:
2500 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2501 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2502 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2503 // This is accomplished by using a BNEZ with the result of the SLT.
2505 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2506 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2507 // Because only BGE and BLE branch on equality, we can use the
2508 // AcceptsEquality variable to decide when to emit the BEQZ.
2509 // Note that the order of the SLT arguments doesn't change between
2512 // The same applies to the unsigned variants, except that SLTu is used
2515 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2516 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2517 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2518 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2519 Instructions.push_back(SetInst);
2521 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2522 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2523 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2524 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2525 Instructions.push_back(BranchInst);
2529 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2530 SmallVectorImpl<MCInst> &Instructions) {
2531 if (hasMips32r6() || hasMips64r6()) {
2532 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2536 warnIfNoMacro(IDLoc);
2538 const MCOperand &DstRegOp = Inst.getOperand(0);
2539 assert(DstRegOp.isReg() && "expected register operand kind");
2541 const MCOperand &SrcRegOp = Inst.getOperand(1);
2542 assert(SrcRegOp.isReg() && "expected register operand kind");
2544 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2545 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2547 unsigned DstReg = DstRegOp.getReg();
2548 unsigned SrcReg = SrcRegOp.getReg();
2549 int64_t OffsetValue = OffsetImmOp.getImm();
2551 // NOTE: We always need AT for ULHU, as it is always used as the source
2552 // register for one of the LBu's.
2553 unsigned ATReg = getATReg(IDLoc);
2557 // When the value of offset+1 does not fit in 16 bits, we have to load the
2558 // offset in AT, (D)ADDu the original source register (if there was one), and
2559 // then use AT as the source register for the 2 generated LBu's.
2560 bool LoadedOffsetInAT = false;
2561 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2562 LoadedOffsetInAT = true;
2564 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2565 IDLoc, Instructions))
2568 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2569 // because it will make our output more similar to GAS'. For example,
2570 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2571 // instead of just an "ori $1, $9, 32768".
2572 // NOTE: If there is no source register specified in the ULHU, the parser
2573 // will interpret it as $0.
2574 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2575 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2578 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2579 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2580 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2582 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2584 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2585 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2587 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2588 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2591 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2594 TmpInst.setOpcode(Mips::LBu);
2595 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2596 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2597 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2598 Instructions.push_back(TmpInst);
2601 TmpInst.setOpcode(Mips::LBu);
2602 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2603 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2604 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2605 Instructions.push_back(TmpInst);
2608 TmpInst.setOpcode(Mips::SLL);
2609 TmpInst.addOperand(MCOperand::createReg(SllReg));
2610 TmpInst.addOperand(MCOperand::createReg(SllReg));
2611 TmpInst.addOperand(MCOperand::createImm(8));
2612 Instructions.push_back(TmpInst);
2615 TmpInst.setOpcode(Mips::OR);
2616 TmpInst.addOperand(MCOperand::createReg(DstReg));
2617 TmpInst.addOperand(MCOperand::createReg(DstReg));
2618 TmpInst.addOperand(MCOperand::createReg(ATReg));
2619 Instructions.push_back(TmpInst);
2624 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2625 SmallVectorImpl<MCInst> &Instructions) {
2626 if (hasMips32r6() || hasMips64r6()) {
2627 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2631 const MCOperand &DstRegOp = Inst.getOperand(0);
2632 assert(DstRegOp.isReg() && "expected register operand kind");
2634 const MCOperand &SrcRegOp = Inst.getOperand(1);
2635 assert(SrcRegOp.isReg() && "expected register operand kind");
2637 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2638 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2640 unsigned SrcReg = SrcRegOp.getReg();
2641 int64_t OffsetValue = OffsetImmOp.getImm();
2644 // When the value of offset+3 does not fit in 16 bits, we have to load the
2645 // offset in AT, (D)ADDu the original source register (if there was one), and
2646 // then use AT as the source register for the generated LWL and LWR.
2647 bool LoadedOffsetInAT = false;
2648 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
2649 ATReg = getATReg(IDLoc);
2652 LoadedOffsetInAT = true;
2654 warnIfNoMacro(IDLoc);
2656 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2657 IDLoc, Instructions))
2660 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2661 // because it will make our output more similar to GAS'. For example,
2662 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2663 // instead of just an "ori $1, $9, 32768".
2664 // NOTE: If there is no source register specified in the ULW, the parser
2665 // will interpret it as $0.
2666 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2667 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2670 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2671 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
2673 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2674 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2676 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2677 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2680 MCInst LeftLoadInst;
2681 LeftLoadInst.setOpcode(Mips::LWL);
2682 LeftLoadInst.addOperand(DstRegOp);
2683 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2684 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
2685 Instructions.push_back(LeftLoadInst);
2687 MCInst RightLoadInst;
2688 RightLoadInst.setOpcode(Mips::LWR);
2689 RightLoadInst.addOperand(DstRegOp);
2690 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2691 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
2692 Instructions.push_back(RightLoadInst);
2697 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2698 SmallVectorImpl<MCInst> &Instructions) {
2700 if (hasShortDelaySlot) {
2701 NopInst.setOpcode(Mips::MOVE16_MM);
2702 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2703 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2705 NopInst.setOpcode(Mips::SLL);
2706 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2707 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2708 NopInst.addOperand(MCOperand::createImm(0));
2710 Instructions.push_back(NopInst);
2713 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2714 unsigned TrgReg, bool Is64Bit,
2715 SmallVectorImpl<MCInst> &Instructions) {
2716 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
2720 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2721 // As described by the Mips32r2 spec, the registers Rd and Rs for
2722 // jalr.hb must be different.
2723 unsigned Opcode = Inst.getOpcode();
2725 if (Opcode == Mips::JALR_HB &&
2726 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2727 return Match_RequiresDifferentSrcAndDst;
2729 return Match_Success;
2732 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2733 OperandVector &Operands,
2735 uint64_t &ErrorInfo,
2736 bool MatchingInlineAsm) {
2739 SmallVector<MCInst, 8> Instructions;
2740 unsigned MatchResult =
2741 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2743 switch (MatchResult) {
2744 case Match_Success: {
2745 if (processInstruction(Inst, IDLoc, Instructions))
2747 for (unsigned i = 0; i < Instructions.size(); i++)
2748 Out.EmitInstruction(Instructions[i], STI);
2751 case Match_MissingFeature:
2752 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2754 case Match_InvalidOperand: {
2755 SMLoc ErrorLoc = IDLoc;
2756 if (ErrorInfo != ~0ULL) {
2757 if (ErrorInfo >= Operands.size())
2758 return Error(IDLoc, "too few operands for instruction");
2760 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2761 if (ErrorLoc == SMLoc())
2765 return Error(ErrorLoc, "invalid operand for instruction");
2767 case Match_MnemonicFail:
2768 return Error(IDLoc, "invalid instruction");
2769 case Match_RequiresDifferentSrcAndDst:
2770 return Error(IDLoc, "source and destination must be different");
2773 llvm_unreachable("Implement any new match types added!");
2776 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2777 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2778 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2779 ") without \".set noat\"");
2782 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2783 if (!AssemblerOptions.back()->isMacro())
2784 Warning(Loc, "macro instruction expanded into multiple instructions");
2788 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2789 SMRange Range, bool ShowColors) {
2790 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2791 Range, SMFixIt(Range, FixMsg),
2795 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2798 CC = StringSwitch<unsigned>(Name)
2834 if (!(isABI_N32() || isABI_N64()))
2837 if (12 <= CC && CC <= 15) {
2838 // Name is one of t4-t7
2839 AsmToken RegTok = getLexer().peekTok();
2840 SMRange RegRange = RegTok.getLocRange();
2842 StringRef FixedName = StringSwitch<StringRef>(Name)
2848 assert(FixedName != "" && "Register name is not one of t4-t7.");
2850 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2851 "Did you mean $" + FixedName + "?", RegRange);
2854 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2855 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2856 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2857 if (8 <= CC && CC <= 11)
2861 CC = StringSwitch<unsigned>(Name)
2873 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2876 CC = StringSwitch<unsigned>(Name)
2877 .Case("hwr_cpunum", 0)
2878 .Case("hwr_synci_step", 1)
2880 .Case("hwr_ccres", 3)
2881 .Case("hwr_ulr", 29)
2887 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2889 if (Name[0] == 'f') {
2890 StringRef NumString = Name.substr(1);
2892 if (NumString.getAsInteger(10, IntVal))
2893 return -1; // This is not an integer.
2894 if (IntVal > 31) // Maximum index for fpu register.
2901 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2903 if (Name.startswith("fcc")) {
2904 StringRef NumString = Name.substr(3);
2906 if (NumString.getAsInteger(10, IntVal))
2907 return -1; // This is not an integer.
2908 if (IntVal > 7) // There are only 8 fcc registers.
2915 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2917 if (Name.startswith("ac")) {
2918 StringRef NumString = Name.substr(2);
2920 if (NumString.getAsInteger(10, IntVal))
2921 return -1; // This is not an integer.
2922 if (IntVal > 3) // There are only 3 acc registers.
2929 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2932 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2941 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2944 CC = StringSwitch<unsigned>(Name)
2947 .Case("msaaccess", 2)
2949 .Case("msamodify", 4)
2950 .Case("msarequest", 5)
2952 .Case("msaunmap", 7)
2958 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2959 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2961 reportParseError(Loc,
2962 "pseudo-instruction requires $at, which is not available");
2965 unsigned AT = getReg(
2966 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2970 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2971 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2974 unsigned MipsAsmParser::getGPR(int RegNo) {
2975 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2979 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2981 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2984 return getReg(RegClass, RegNum);
2987 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2988 MCAsmParser &Parser = getParser();
2989 DEBUG(dbgs() << "parseOperand\n");
2991 // Check if the current operand has a custom associated parser, if so, try to
2992 // custom parse the operand, or fallback to the general approach.
2993 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2994 if (ResTy == MatchOperand_Success)
2996 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2997 // there was a match, but an error occurred, in which case, just return that
2998 // the operand parsing failed.
2999 if (ResTy == MatchOperand_ParseFail)
3002 DEBUG(dbgs() << ".. Generic Parser\n");
3004 switch (getLexer().getKind()) {
3006 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3008 case AsmToken::Dollar: {
3009 // Parse the register.
3010 SMLoc S = Parser.getTok().getLoc();
3012 // Almost all registers have been parsed by custom parsers. There is only
3013 // one exception to this. $zero (and it's alias $0) will reach this point
3014 // for div, divu, and similar instructions because it is not an operand
3015 // to the instruction definition but an explicit register. Special case
3016 // this situation for now.
3017 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3020 // Maybe it is a symbol reference.
3021 StringRef Identifier;
3022 if (Parser.parseIdentifier(Identifier))
3025 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3026 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3027 // Otherwise create a symbol reference.
3029 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3031 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3034 // Else drop to expression parsing.
3035 case AsmToken::LParen:
3036 case AsmToken::Minus:
3037 case AsmToken::Plus:
3038 case AsmToken::Integer:
3039 case AsmToken::Tilde:
3040 case AsmToken::String: {
3041 DEBUG(dbgs() << ".. generic integer\n");
3042 OperandMatchResultTy ResTy = parseImm(Operands);
3043 return ResTy != MatchOperand_Success;
3045 case AsmToken::Percent: {
3046 // It is a symbol reference or constant expression.
3047 const MCExpr *IdVal;
3048 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3049 if (parseRelocOperand(IdVal))
3052 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3054 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3056 } // case AsmToken::Percent
3057 } // switch(getLexer().getKind())
3061 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3062 StringRef RelocStr) {
3064 // Check the type of the expression.
3065 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3066 // It's a constant, evaluate reloc value.
3068 switch (getVariantKind(RelocStr)) {
3069 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3070 // Get the 1st 16-bits.
3071 Val = MCE->getValue() & 0xffff;
3073 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3074 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3075 // 16 bits being negative.
3076 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3078 case MCSymbolRefExpr::VK_Mips_HIGHER:
3079 // Get the 3rd 16-bits.
3080 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3082 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3083 // Get the 4th 16-bits.
3084 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3087 report_fatal_error("unsupported reloc value");
3089 return MCConstantExpr::create(Val, getContext());
3092 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3093 // It's a symbol, create a symbolic expression from the symbol.
3094 const MCSymbol *Symbol = &MSRE->getSymbol();
3095 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3096 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3100 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3101 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3103 // Try to create target expression.
3104 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3105 return MipsMCExpr::create(VK, Expr, getContext());
3107 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3108 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3109 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3113 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3114 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3115 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3118 // Just return the original expression.
3122 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3124 switch (Expr->getKind()) {
3125 case MCExpr::Constant:
3127 case MCExpr::SymbolRef:
3128 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3129 case MCExpr::Binary:
3130 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3131 if (!isEvaluated(BE->getLHS()))
3133 return isEvaluated(BE->getRHS());
3136 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3137 case MCExpr::Target:
3143 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3144 MCAsmParser &Parser = getParser();
3145 Parser.Lex(); // Eat the % token.
3146 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3147 if (Tok.isNot(AsmToken::Identifier))
3150 std::string Str = Tok.getIdentifier();
3152 Parser.Lex(); // Eat the identifier.
3153 // Now make an expression from the rest of the operand.
3154 const MCExpr *IdVal;
3157 if (getLexer().getKind() == AsmToken::LParen) {
3159 Parser.Lex(); // Eat the '(' token.
3160 if (getLexer().getKind() == AsmToken::Percent) {
3161 Parser.Lex(); // Eat the % token.
3162 const AsmToken &nextTok = Parser.getTok();
3163 if (nextTok.isNot(AsmToken::Identifier))
3166 Str += nextTok.getIdentifier();
3167 Parser.Lex(); // Eat the identifier.
3168 if (getLexer().getKind() != AsmToken::LParen)
3173 if (getParser().parseParenExpression(IdVal, EndLoc))
3176 while (getLexer().getKind() == AsmToken::RParen)
3177 Parser.Lex(); // Eat the ')' token.
3180 return true; // Parenthesis must follow the relocation operand.
3182 Res = evaluateRelocExpr(IdVal, Str);
3186 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3188 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3189 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3190 if (ResTy == MatchOperand_Success) {
3191 assert(Operands.size() == 1);
3192 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3193 StartLoc = Operand.getStartLoc();
3194 EndLoc = Operand.getEndLoc();
3196 // AFAIK, we only support numeric registers and named GPR's in CFI
3198 // Don't worry about eating tokens before failing. Using an unrecognised
3199 // register is a parse error.
3200 if (Operand.isGPRAsmReg()) {
3201 // Resolve to GPR32 or GPR64 appropriately.
3202 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3205 return (RegNo == (unsigned)-1);
3208 assert(Operands.size() == 0);
3209 return (RegNo == (unsigned)-1);
3212 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3213 MCAsmParser &Parser = getParser();
3216 unsigned NumOfLParen = 0;
3218 while (getLexer().getKind() == AsmToken::LParen) {
3223 switch (getLexer().getKind()) {
3226 case AsmToken::Identifier:
3227 case AsmToken::LParen:
3228 case AsmToken::Integer:
3229 case AsmToken::Minus:
3230 case AsmToken::Plus:
3232 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3234 Result = (getParser().parseExpression(Res));
3235 while (getLexer().getKind() == AsmToken::RParen)
3238 case AsmToken::Percent:
3239 Result = parseRelocOperand(Res);
3244 MipsAsmParser::OperandMatchResultTy
3245 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3246 MCAsmParser &Parser = getParser();
3247 DEBUG(dbgs() << "parseMemOperand\n");
3248 const MCExpr *IdVal = nullptr;
3250 bool isParenExpr = false;
3251 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3252 // First operand is the offset.
3253 S = Parser.getTok().getLoc();
3255 if (getLexer().getKind() == AsmToken::LParen) {
3260 if (getLexer().getKind() != AsmToken::Dollar) {
3261 if (parseMemOffset(IdVal, isParenExpr))
3262 return MatchOperand_ParseFail;
3264 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3265 if (Tok.isNot(AsmToken::LParen)) {
3266 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3267 if (Mnemonic.getToken() == "la") {
3269 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3270 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3271 return MatchOperand_Success;
3273 if (Tok.is(AsmToken::EndOfStatement)) {
3275 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3277 // Zero register assumed, add a memory operand with ZERO as its base.
3278 // "Base" will be managed by k_Memory.
3279 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3282 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3283 return MatchOperand_Success;
3285 Error(Parser.getTok().getLoc(), "'(' expected");
3286 return MatchOperand_ParseFail;
3289 Parser.Lex(); // Eat the '(' token.
3292 Res = parseAnyRegister(Operands);
3293 if (Res != MatchOperand_Success)
3296 if (Parser.getTok().isNot(AsmToken::RParen)) {
3297 Error(Parser.getTok().getLoc(), "')' expected");
3298 return MatchOperand_ParseFail;
3301 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3303 Parser.Lex(); // Eat the ')' token.
3306 IdVal = MCConstantExpr::create(0, getContext());
3308 // Replace the register operand with the memory operand.
3309 std::unique_ptr<MipsOperand> op(
3310 static_cast<MipsOperand *>(Operands.back().release()));
3311 // Remove the register from the operands.
3312 // "op" will be managed by k_Memory.
3313 Operands.pop_back();
3314 // Add the memory operand.
3315 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3317 if (IdVal->evaluateAsAbsolute(Imm))
3318 IdVal = MCConstantExpr::create(Imm, getContext());
3319 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3320 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3324 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3325 return MatchOperand_Success;
3328 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3329 MCAsmParser &Parser = getParser();
3330 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3332 SMLoc S = Parser.getTok().getLoc();
3334 if (Sym->isVariable())
3335 Expr = Sym->getVariableValue();
3338 if (Expr->getKind() == MCExpr::SymbolRef) {
3339 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3340 StringRef DefSymbol = Ref->getSymbol().getName();
3341 if (DefSymbol.startswith("$")) {
3342 OperandMatchResultTy ResTy =
3343 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3344 if (ResTy == MatchOperand_Success) {
3347 } else if (ResTy == MatchOperand_ParseFail)
3348 llvm_unreachable("Should never ParseFail");
3351 } else if (Expr->getKind() == MCExpr::Constant) {
3353 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3355 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3362 MipsAsmParser::OperandMatchResultTy
3363 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3364 StringRef Identifier,
3366 int Index = matchCPURegisterName(Identifier);
3368 Operands.push_back(MipsOperand::createGPRReg(
3369 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3370 return MatchOperand_Success;
3373 Index = matchHWRegsRegisterName(Identifier);
3375 Operands.push_back(MipsOperand::createHWRegsReg(
3376 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3377 return MatchOperand_Success;
3380 Index = matchFPURegisterName(Identifier);
3382 Operands.push_back(MipsOperand::createFGRReg(
3383 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3384 return MatchOperand_Success;
3387 Index = matchFCCRegisterName(Identifier);
3389 Operands.push_back(MipsOperand::createFCCReg(
3390 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3391 return MatchOperand_Success;
3394 Index = matchACRegisterName(Identifier);
3396 Operands.push_back(MipsOperand::createACCReg(
3397 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3398 return MatchOperand_Success;
3401 Index = matchMSA128RegisterName(Identifier);
3403 Operands.push_back(MipsOperand::createMSA128Reg(
3404 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3405 return MatchOperand_Success;
3408 Index = matchMSA128CtrlRegisterName(Identifier);
3410 Operands.push_back(MipsOperand::createMSACtrlReg(
3411 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3412 return MatchOperand_Success;
3415 return MatchOperand_NoMatch;
3418 MipsAsmParser::OperandMatchResultTy
3419 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3420 MCAsmParser &Parser = getParser();
3421 auto Token = Parser.getLexer().peekTok(false);
3423 if (Token.is(AsmToken::Identifier)) {
3424 DEBUG(dbgs() << ".. identifier\n");
3425 StringRef Identifier = Token.getIdentifier();
3426 OperandMatchResultTy ResTy =
3427 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3429 } else if (Token.is(AsmToken::Integer)) {
3430 DEBUG(dbgs() << ".. integer\n");
3431 Operands.push_back(MipsOperand::createNumericReg(
3432 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3434 return MatchOperand_Success;
3437 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3439 return MatchOperand_NoMatch;
3442 MipsAsmParser::OperandMatchResultTy
3443 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3444 MCAsmParser &Parser = getParser();
3445 DEBUG(dbgs() << "parseAnyRegister\n");
3447 auto Token = Parser.getTok();
3449 SMLoc S = Token.getLoc();
3451 if (Token.isNot(AsmToken::Dollar)) {
3452 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3453 if (Token.is(AsmToken::Identifier)) {
3454 if (searchSymbolAlias(Operands))
3455 return MatchOperand_Success;
3457 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3458 return MatchOperand_NoMatch;
3460 DEBUG(dbgs() << ".. $\n");
3462 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3463 if (ResTy == MatchOperand_Success) {
3465 Parser.Lex(); // identifier
3470 MipsAsmParser::OperandMatchResultTy
3471 MipsAsmParser::parseImm(OperandVector &Operands) {
3472 MCAsmParser &Parser = getParser();
3473 switch (getLexer().getKind()) {
3475 return MatchOperand_NoMatch;
3476 case AsmToken::LParen:
3477 case AsmToken::Minus:
3478 case AsmToken::Plus:
3479 case AsmToken::Integer:
3480 case AsmToken::Tilde:
3481 case AsmToken::String:
3485 const MCExpr *IdVal;
3486 SMLoc S = Parser.getTok().getLoc();
3487 if (getParser().parseExpression(IdVal))
3488 return MatchOperand_ParseFail;
3490 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3491 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3492 return MatchOperand_Success;
3495 MipsAsmParser::OperandMatchResultTy
3496 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3497 MCAsmParser &Parser = getParser();
3498 DEBUG(dbgs() << "parseJumpTarget\n");
3500 SMLoc S = getLexer().getLoc();
3502 // Integers and expressions are acceptable
3503 OperandMatchResultTy ResTy = parseImm(Operands);
3504 if (ResTy != MatchOperand_NoMatch)
3507 // Registers are a valid target and have priority over symbols.
3508 ResTy = parseAnyRegister(Operands);
3509 if (ResTy != MatchOperand_NoMatch)
3512 const MCExpr *Expr = nullptr;
3513 if (Parser.parseExpression(Expr)) {
3514 // We have no way of knowing if a symbol was consumed so we must ParseFail
3515 return MatchOperand_ParseFail;
3518 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3519 return MatchOperand_Success;
3522 MipsAsmParser::OperandMatchResultTy
3523 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3524 MCAsmParser &Parser = getParser();
3525 const MCExpr *IdVal;
3526 // If the first token is '$' we may have register operand.
3527 if (Parser.getTok().is(AsmToken::Dollar))
3528 return MatchOperand_NoMatch;
3529 SMLoc S = Parser.getTok().getLoc();
3530 if (getParser().parseExpression(IdVal))
3531 return MatchOperand_ParseFail;
3532 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3533 assert(MCE && "Unexpected MCExpr type.");
3534 int64_t Val = MCE->getValue();
3535 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3536 Operands.push_back(MipsOperand::CreateImm(
3537 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3538 return MatchOperand_Success;
3541 MipsAsmParser::OperandMatchResultTy
3542 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3543 MCAsmParser &Parser = getParser();
3544 switch (getLexer().getKind()) {
3546 return MatchOperand_NoMatch;
3547 case AsmToken::LParen:
3548 case AsmToken::Plus:
3549 case AsmToken::Minus:
3550 case AsmToken::Integer:
3555 SMLoc S = Parser.getTok().getLoc();
3557 if (getParser().parseExpression(Expr))
3558 return MatchOperand_ParseFail;
3561 if (!Expr->evaluateAsAbsolute(Val)) {
3562 Error(S, "expected immediate value");
3563 return MatchOperand_ParseFail;
3566 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3567 // and because the CPU always adds one to the immediate field, the allowed
3568 // range becomes 1..4. We'll only check the range here and will deal
3569 // with the addition/subtraction when actually decoding/encoding
3571 if (Val < 1 || Val > 4) {
3572 Error(S, "immediate not in range (1..4)");
3573 return MatchOperand_ParseFail;
3577 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3578 return MatchOperand_Success;
3581 MipsAsmParser::OperandMatchResultTy
3582 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3583 MCAsmParser &Parser = getParser();
3584 SmallVector<unsigned, 10> Regs;
3586 unsigned PrevReg = Mips::NoRegister;
3587 bool RegRange = false;
3588 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3590 if (Parser.getTok().isNot(AsmToken::Dollar))
3591 return MatchOperand_ParseFail;
3593 SMLoc S = Parser.getTok().getLoc();
3594 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3595 SMLoc E = getLexer().getLoc();
3596 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3597 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3599 // Remove last register operand because registers from register range
3600 // should be inserted first.
3601 if (RegNo == Mips::RA) {
3602 Regs.push_back(RegNo);
3604 unsigned TmpReg = PrevReg + 1;
3605 while (TmpReg <= RegNo) {
3606 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3607 Error(E, "invalid register operand");
3608 return MatchOperand_ParseFail;
3612 Regs.push_back(TmpReg++);
3618 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3619 (RegNo != Mips::RA)) {
3620 Error(E, "$16 or $31 expected");
3621 return MatchOperand_ParseFail;
3622 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3623 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3624 Error(E, "invalid register operand");
3625 return MatchOperand_ParseFail;
3626 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3627 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3628 Error(E, "consecutive register numbers expected");
3629 return MatchOperand_ParseFail;
3632 Regs.push_back(RegNo);
3635 if (Parser.getTok().is(AsmToken::Minus))
3638 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3639 !Parser.getTok().isNot(AsmToken::Comma)) {
3640 Error(E, "',' or '-' expected");
3641 return MatchOperand_ParseFail;
3644 Lex(); // Consume comma or minus
3645 if (Parser.getTok().isNot(AsmToken::Dollar))
3651 SMLoc E = Parser.getTok().getLoc();
3652 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3653 parseMemOperand(Operands);
3654 return MatchOperand_Success;
3657 MipsAsmParser::OperandMatchResultTy
3658 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3659 MCAsmParser &Parser = getParser();
3661 SMLoc S = Parser.getTok().getLoc();
3662 if (parseAnyRegister(Operands) != MatchOperand_Success)
3663 return MatchOperand_ParseFail;
3665 SMLoc E = Parser.getTok().getLoc();
3666 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3667 unsigned Reg = Op.getGPR32Reg();
3668 Operands.pop_back();
3669 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3670 return MatchOperand_Success;
3673 MipsAsmParser::OperandMatchResultTy
3674 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3675 MCAsmParser &Parser = getParser();
3676 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3677 SmallVector<unsigned, 10> Regs;
3679 if (Parser.getTok().isNot(AsmToken::Dollar))
3680 return MatchOperand_ParseFail;
3682 SMLoc S = Parser.getTok().getLoc();
3684 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3685 return MatchOperand_ParseFail;
3687 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3688 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3689 Regs.push_back(RegNo);
3691 SMLoc E = Parser.getTok().getLoc();
3692 if (Parser.getTok().isNot(AsmToken::Comma)) {
3693 Error(E, "',' expected");
3694 return MatchOperand_ParseFail;
3700 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3701 return MatchOperand_ParseFail;
3703 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3704 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3705 Regs.push_back(RegNo);
3707 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3709 return MatchOperand_Success;
3712 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3714 MCSymbolRefExpr::VariantKind VK =
3715 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3716 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3717 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3718 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3719 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3720 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3721 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3722 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3723 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3724 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3725 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3726 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3727 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3728 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3729 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3730 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3731 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3732 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3733 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3734 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3735 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3736 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3737 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3738 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3739 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3740 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3741 .Default(MCSymbolRefExpr::VK_None);
3743 assert(VK != MCSymbolRefExpr::VK_None);
3748 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3750 /// ::= '(', register, ')'
3751 /// handle it before we iterate so we don't get tripped up by the lack of
3753 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3754 MCAsmParser &Parser = getParser();
3755 if (getLexer().is(AsmToken::LParen)) {
3757 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3759 if (parseOperand(Operands, Name)) {
3760 SMLoc Loc = getLexer().getLoc();
3761 Parser.eatToEndOfStatement();
3762 return Error(Loc, "unexpected token in argument list");
3764 if (Parser.getTok().isNot(AsmToken::RParen)) {
3765 SMLoc Loc = getLexer().getLoc();
3766 Parser.eatToEndOfStatement();
3767 return Error(Loc, "unexpected token, expected ')'");
3770 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3776 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3777 /// either one of these.
3778 /// ::= '[', register, ']'
3779 /// ::= '[', integer, ']'
3780 /// handle it before we iterate so we don't get tripped up by the lack of
3782 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3783 OperandVector &Operands) {
3784 MCAsmParser &Parser = getParser();
3785 if (getLexer().is(AsmToken::LBrac)) {
3787 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3789 if (parseOperand(Operands, Name)) {
3790 SMLoc Loc = getLexer().getLoc();
3791 Parser.eatToEndOfStatement();
3792 return Error(Loc, "unexpected token in argument list");
3794 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3795 SMLoc Loc = getLexer().getLoc();
3796 Parser.eatToEndOfStatement();
3797 return Error(Loc, "unexpected token, expected ']'");
3800 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3806 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3807 SMLoc NameLoc, OperandVector &Operands) {
3808 MCAsmParser &Parser = getParser();
3809 DEBUG(dbgs() << "ParseInstruction\n");
3811 // We have reached first instruction, module directive are now forbidden.
3812 getTargetStreamer().forbidModuleDirective();
3814 // Check if we have valid mnemonic
3815 if (!mnemonicIsValid(Name, 0)) {
3816 Parser.eatToEndOfStatement();
3817 return Error(NameLoc, "unknown instruction");
3819 // First operand in MCInst is instruction mnemonic.
3820 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3822 // Read the remaining operands.
3823 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3824 // Read the first operand.
3825 if (parseOperand(Operands, Name)) {
3826 SMLoc Loc = getLexer().getLoc();
3827 Parser.eatToEndOfStatement();
3828 return Error(Loc, "unexpected token in argument list");
3830 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3832 // AFAIK, parenthesis suffixes are never on the first operand
3834 while (getLexer().is(AsmToken::Comma)) {
3835 Parser.Lex(); // Eat the comma.
3836 // Parse and remember the operand.
3837 if (parseOperand(Operands, Name)) {
3838 SMLoc Loc = getLexer().getLoc();
3839 Parser.eatToEndOfStatement();
3840 return Error(Loc, "unexpected token in argument list");
3842 // Parse bracket and parenthesis suffixes before we iterate
3843 if (getLexer().is(AsmToken::LBrac)) {
3844 if (parseBracketSuffix(Name, Operands))
3846 } else if (getLexer().is(AsmToken::LParen) &&
3847 parseParenSuffix(Name, Operands))
3851 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3852 SMLoc Loc = getLexer().getLoc();
3853 Parser.eatToEndOfStatement();
3854 return Error(Loc, "unexpected token in argument list");
3856 Parser.Lex(); // Consume the EndOfStatement.
3860 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3861 MCAsmParser &Parser = getParser();
3862 SMLoc Loc = getLexer().getLoc();
3863 Parser.eatToEndOfStatement();
3864 return Error(Loc, ErrorMsg);
3867 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3868 return Error(Loc, ErrorMsg);
3871 bool MipsAsmParser::parseSetNoAtDirective() {
3872 MCAsmParser &Parser = getParser();
3873 // Line should look like: ".set noat".
3875 // Set the $at register to $0.
3876 AssemblerOptions.back()->setATRegIndex(0);
3878 Parser.Lex(); // Eat "noat".
3880 // If this is not the end of the statement, report an error.
3881 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3882 reportParseError("unexpected token, expected end of statement");
3886 getTargetStreamer().emitDirectiveSetNoAt();
3887 Parser.Lex(); // Consume the EndOfStatement.
3891 bool MipsAsmParser::parseSetAtDirective() {
3892 // Line can be: ".set at", which sets $at to $1
3893 // or ".set at=$reg", which sets $at to $reg.
3894 MCAsmParser &Parser = getParser();
3895 Parser.Lex(); // Eat "at".
3897 if (getLexer().is(AsmToken::EndOfStatement)) {
3898 // No register was specified, so we set $at to $1.
3899 AssemblerOptions.back()->setATRegIndex(1);
3901 getTargetStreamer().emitDirectiveSetAt();
3902 Parser.Lex(); // Consume the EndOfStatement.
3906 if (getLexer().isNot(AsmToken::Equal)) {
3907 reportParseError("unexpected token, expected equals sign");
3910 Parser.Lex(); // Eat "=".
3912 if (getLexer().isNot(AsmToken::Dollar)) {
3913 if (getLexer().is(AsmToken::EndOfStatement)) {
3914 reportParseError("no register specified");
3917 reportParseError("unexpected token, expected dollar sign '$'");
3921 Parser.Lex(); // Eat "$".
3923 // Find out what "reg" is.
3925 const AsmToken &Reg = Parser.getTok();
3926 if (Reg.is(AsmToken::Identifier)) {
3927 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3928 } else if (Reg.is(AsmToken::Integer)) {
3929 AtRegNo = Reg.getIntVal();
3931 reportParseError("unexpected token, expected identifier or integer");
3935 // Check if $reg is a valid register. If it is, set $at to $reg.
3936 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3937 reportParseError("invalid register");
3940 Parser.Lex(); // Eat "reg".
3942 // If this is not the end of the statement, report an error.
3943 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3944 reportParseError("unexpected token, expected end of statement");
3948 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3950 Parser.Lex(); // Consume the EndOfStatement.
3954 bool MipsAsmParser::parseSetReorderDirective() {
3955 MCAsmParser &Parser = getParser();
3957 // If this is not the end of the statement, report an error.
3958 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3959 reportParseError("unexpected token, expected end of statement");
3962 AssemblerOptions.back()->setReorder();
3963 getTargetStreamer().emitDirectiveSetReorder();
3964 Parser.Lex(); // Consume the EndOfStatement.
3968 bool MipsAsmParser::parseSetNoReorderDirective() {
3969 MCAsmParser &Parser = getParser();
3971 // If this is not the end of the statement, report an error.
3972 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3973 reportParseError("unexpected token, expected end of statement");
3976 AssemblerOptions.back()->setNoReorder();
3977 getTargetStreamer().emitDirectiveSetNoReorder();
3978 Parser.Lex(); // Consume the EndOfStatement.
3982 bool MipsAsmParser::parseSetMacroDirective() {
3983 MCAsmParser &Parser = getParser();
3985 // If this is not the end of the statement, report an error.
3986 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3987 reportParseError("unexpected token, expected end of statement");
3990 AssemblerOptions.back()->setMacro();
3991 getTargetStreamer().emitDirectiveSetMacro();
3992 Parser.Lex(); // Consume the EndOfStatement.
3996 bool MipsAsmParser::parseSetNoMacroDirective() {
3997 MCAsmParser &Parser = getParser();
3999 // If this is not the end of the statement, report an error.
4000 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4001 reportParseError("unexpected token, expected end of statement");
4004 if (AssemblerOptions.back()->isReorder()) {
4005 reportParseError("`noreorder' must be set before `nomacro'");
4008 AssemblerOptions.back()->setNoMacro();
4009 getTargetStreamer().emitDirectiveSetNoMacro();
4010 Parser.Lex(); // Consume the EndOfStatement.
4014 bool MipsAsmParser::parseSetMsaDirective() {
4015 MCAsmParser &Parser = getParser();
4018 // If this is not the end of the statement, report an error.
4019 if (getLexer().isNot(AsmToken::EndOfStatement))
4020 return reportParseError("unexpected token, expected end of statement");
4022 setFeatureBits(Mips::FeatureMSA, "msa");
4023 getTargetStreamer().emitDirectiveSetMsa();
4027 bool MipsAsmParser::parseSetNoMsaDirective() {
4028 MCAsmParser &Parser = getParser();
4031 // If this is not the end of the statement, report an error.
4032 if (getLexer().isNot(AsmToken::EndOfStatement))
4033 return reportParseError("unexpected token, expected end of statement");
4035 clearFeatureBits(Mips::FeatureMSA, "msa");
4036 getTargetStreamer().emitDirectiveSetNoMsa();
4040 bool MipsAsmParser::parseSetNoDspDirective() {
4041 MCAsmParser &Parser = getParser();
4042 Parser.Lex(); // Eat "nodsp".
4044 // If this is not the end of the statement, report an error.
4045 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4046 reportParseError("unexpected token, expected end of statement");
4050 clearFeatureBits(Mips::FeatureDSP, "dsp");
4051 getTargetStreamer().emitDirectiveSetNoDsp();
4055 bool MipsAsmParser::parseSetMips16Directive() {
4056 MCAsmParser &Parser = getParser();
4057 Parser.Lex(); // Eat "mips16".
4059 // If this is not the end of the statement, report an error.
4060 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4061 reportParseError("unexpected token, expected end of statement");
4065 setFeatureBits(Mips::FeatureMips16, "mips16");
4066 getTargetStreamer().emitDirectiveSetMips16();
4067 Parser.Lex(); // Consume the EndOfStatement.
4071 bool MipsAsmParser::parseSetNoMips16Directive() {
4072 MCAsmParser &Parser = getParser();
4073 Parser.Lex(); // Eat "nomips16".
4075 // If this is not the end of the statement, report an error.
4076 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4077 reportParseError("unexpected token, expected end of statement");
4081 clearFeatureBits(Mips::FeatureMips16, "mips16");
4082 getTargetStreamer().emitDirectiveSetNoMips16();
4083 Parser.Lex(); // Consume the EndOfStatement.
4087 bool MipsAsmParser::parseSetFpDirective() {
4088 MCAsmParser &Parser = getParser();
4089 MipsABIFlagsSection::FpABIKind FpAbiVal;
4090 // Line can be: .set fp=32
4093 Parser.Lex(); // Eat fp token
4094 AsmToken Tok = Parser.getTok();
4095 if (Tok.isNot(AsmToken::Equal)) {
4096 reportParseError("unexpected token, expected equals sign '='");
4099 Parser.Lex(); // Eat '=' token.
4100 Tok = Parser.getTok();
4102 if (!parseFpABIValue(FpAbiVal, ".set"))
4105 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4106 reportParseError("unexpected token, expected end of statement");
4109 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4110 Parser.Lex(); // Consume the EndOfStatement.
4114 bool MipsAsmParser::parseSetOddSPRegDirective() {
4115 MCAsmParser &Parser = getParser();
4117 Parser.Lex(); // Eat "oddspreg".
4118 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4119 reportParseError("unexpected token, expected end of statement");
4123 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4124 getTargetStreamer().emitDirectiveSetOddSPReg();
4128 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4129 MCAsmParser &Parser = getParser();
4131 Parser.Lex(); // Eat "nooddspreg".
4132 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4133 reportParseError("unexpected token, expected end of statement");
4137 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4138 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4142 bool MipsAsmParser::parseSetPopDirective() {
4143 MCAsmParser &Parser = getParser();
4144 SMLoc Loc = getLexer().getLoc();
4147 if (getLexer().isNot(AsmToken::EndOfStatement))
4148 return reportParseError("unexpected token, expected end of statement");
4150 // Always keep an element on the options "stack" to prevent the user
4151 // from changing the initial options. This is how we remember them.
4152 if (AssemblerOptions.size() == 2)
4153 return reportParseError(Loc, ".set pop with no .set push");
4155 AssemblerOptions.pop_back();
4156 setAvailableFeatures(
4157 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4158 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4160 getTargetStreamer().emitDirectiveSetPop();
4164 bool MipsAsmParser::parseSetPushDirective() {
4165 MCAsmParser &Parser = getParser();
4167 if (getLexer().isNot(AsmToken::EndOfStatement))
4168 return reportParseError("unexpected token, expected end of statement");
4170 // Create a copy of the current assembler options environment and push it.
4171 AssemblerOptions.push_back(
4172 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4174 getTargetStreamer().emitDirectiveSetPush();
4178 bool MipsAsmParser::parseSetSoftFloatDirective() {
4179 MCAsmParser &Parser = getParser();
4181 if (getLexer().isNot(AsmToken::EndOfStatement))
4182 return reportParseError("unexpected token, expected end of statement");
4184 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4185 getTargetStreamer().emitDirectiveSetSoftFloat();
4189 bool MipsAsmParser::parseSetHardFloatDirective() {
4190 MCAsmParser &Parser = getParser();
4192 if (getLexer().isNot(AsmToken::EndOfStatement))
4193 return reportParseError("unexpected token, expected end of statement");
4195 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4196 getTargetStreamer().emitDirectiveSetHardFloat();
4200 bool MipsAsmParser::parseSetAssignment() {
4202 const MCExpr *Value;
4203 MCAsmParser &Parser = getParser();
4205 if (Parser.parseIdentifier(Name))
4206 reportParseError("expected identifier after .set");
4208 if (getLexer().isNot(AsmToken::Comma))
4209 return reportParseError("unexpected token, expected comma");
4212 if (Parser.parseExpression(Value))
4213 return reportParseError("expected valid expression after comma");
4215 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4216 Sym->setVariableValue(Value);
4221 bool MipsAsmParser::parseSetMips0Directive() {
4222 MCAsmParser &Parser = getParser();
4224 if (getLexer().isNot(AsmToken::EndOfStatement))
4225 return reportParseError("unexpected token, expected end of statement");
4227 // Reset assembler options to their initial values.
4228 setAvailableFeatures(
4229 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4230 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4231 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4233 getTargetStreamer().emitDirectiveSetMips0();
4237 bool MipsAsmParser::parseSetArchDirective() {
4238 MCAsmParser &Parser = getParser();
4240 if (getLexer().isNot(AsmToken::Equal))
4241 return reportParseError("unexpected token, expected equals sign");
4245 if (Parser.parseIdentifier(Arch))
4246 return reportParseError("expected arch identifier");
4248 StringRef ArchFeatureName =
4249 StringSwitch<StringRef>(Arch)
4250 .Case("mips1", "mips1")
4251 .Case("mips2", "mips2")
4252 .Case("mips3", "mips3")
4253 .Case("mips4", "mips4")
4254 .Case("mips5", "mips5")
4255 .Case("mips32", "mips32")
4256 .Case("mips32r2", "mips32r2")
4257 .Case("mips32r3", "mips32r3")
4258 .Case("mips32r5", "mips32r5")
4259 .Case("mips32r6", "mips32r6")
4260 .Case("mips64", "mips64")
4261 .Case("mips64r2", "mips64r2")
4262 .Case("mips64r3", "mips64r3")
4263 .Case("mips64r5", "mips64r5")
4264 .Case("mips64r6", "mips64r6")
4265 .Case("cnmips", "cnmips")
4266 .Case("r4000", "mips3") // This is an implementation of Mips3.
4269 if (ArchFeatureName.empty())
4270 return reportParseError("unsupported architecture");
4272 selectArch(ArchFeatureName);
4273 getTargetStreamer().emitDirectiveSetArch(Arch);
4277 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4278 MCAsmParser &Parser = getParser();
4280 if (getLexer().isNot(AsmToken::EndOfStatement))
4281 return reportParseError("unexpected token, expected end of statement");
4285 llvm_unreachable("Unimplemented feature");
4286 case Mips::FeatureDSP:
4287 setFeatureBits(Mips::FeatureDSP, "dsp");
4288 getTargetStreamer().emitDirectiveSetDsp();
4290 case Mips::FeatureMicroMips:
4291 getTargetStreamer().emitDirectiveSetMicroMips();
4293 case Mips::FeatureMips1:
4294 selectArch("mips1");
4295 getTargetStreamer().emitDirectiveSetMips1();
4297 case Mips::FeatureMips2:
4298 selectArch("mips2");
4299 getTargetStreamer().emitDirectiveSetMips2();
4301 case Mips::FeatureMips3:
4302 selectArch("mips3");
4303 getTargetStreamer().emitDirectiveSetMips3();
4305 case Mips::FeatureMips4:
4306 selectArch("mips4");
4307 getTargetStreamer().emitDirectiveSetMips4();
4309 case Mips::FeatureMips5:
4310 selectArch("mips5");
4311 getTargetStreamer().emitDirectiveSetMips5();
4313 case Mips::FeatureMips32:
4314 selectArch("mips32");
4315 getTargetStreamer().emitDirectiveSetMips32();
4317 case Mips::FeatureMips32r2:
4318 selectArch("mips32r2");
4319 getTargetStreamer().emitDirectiveSetMips32R2();
4321 case Mips::FeatureMips32r3:
4322 selectArch("mips32r3");
4323 getTargetStreamer().emitDirectiveSetMips32R3();
4325 case Mips::FeatureMips32r5:
4326 selectArch("mips32r5");
4327 getTargetStreamer().emitDirectiveSetMips32R5();
4329 case Mips::FeatureMips32r6:
4330 selectArch("mips32r6");
4331 getTargetStreamer().emitDirectiveSetMips32R6();
4333 case Mips::FeatureMips64:
4334 selectArch("mips64");
4335 getTargetStreamer().emitDirectiveSetMips64();
4337 case Mips::FeatureMips64r2:
4338 selectArch("mips64r2");
4339 getTargetStreamer().emitDirectiveSetMips64R2();
4341 case Mips::FeatureMips64r3:
4342 selectArch("mips64r3");
4343 getTargetStreamer().emitDirectiveSetMips64R3();
4345 case Mips::FeatureMips64r5:
4346 selectArch("mips64r5");
4347 getTargetStreamer().emitDirectiveSetMips64R5();
4349 case Mips::FeatureMips64r6:
4350 selectArch("mips64r6");
4351 getTargetStreamer().emitDirectiveSetMips64R6();
4357 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4358 MCAsmParser &Parser = getParser();
4359 if (getLexer().isNot(AsmToken::Comma)) {
4360 SMLoc Loc = getLexer().getLoc();
4361 Parser.eatToEndOfStatement();
4362 return Error(Loc, ErrorStr);
4365 Parser.Lex(); // Eat the comma.
4369 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4370 if (AssemblerOptions.back()->isReorder())
4371 Warning(Loc, ".cpload should be inside a noreorder section");
4373 if (inMips16Mode()) {
4374 reportParseError(".cpload is not supported in Mips16 mode");
4378 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4379 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4380 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4381 reportParseError("expected register containing function address");
4385 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4386 if (!RegOpnd.isGPRAsmReg()) {
4387 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4391 // If this is not the end of the statement, report an error.
4392 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4393 reportParseError("unexpected token, expected end of statement");
4397 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4401 bool MipsAsmParser::parseDirectiveCPSetup() {
4402 MCAsmParser &Parser = getParser();
4405 bool SaveIsReg = true;
4407 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4408 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4409 if (ResTy == MatchOperand_NoMatch) {
4410 reportParseError("expected register containing function address");
4411 Parser.eatToEndOfStatement();
4415 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4416 if (!FuncRegOpnd.isGPRAsmReg()) {
4417 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4418 Parser.eatToEndOfStatement();
4422 FuncReg = FuncRegOpnd.getGPR32Reg();
4425 if (!eatComma("unexpected token, expected comma"))
4428 ResTy = parseAnyRegister(TmpReg);
4429 if (ResTy == MatchOperand_NoMatch) {
4430 const AsmToken &Tok = Parser.getTok();
4431 if (Tok.is(AsmToken::Integer)) {
4432 Save = Tok.getIntVal();
4436 reportParseError("expected save register or stack offset");
4437 Parser.eatToEndOfStatement();
4441 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4442 if (!SaveOpnd.isGPRAsmReg()) {
4443 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4444 Parser.eatToEndOfStatement();
4447 Save = SaveOpnd.getGPR32Reg();
4450 if (!eatComma("unexpected token, expected comma"))
4454 if (Parser.parseExpression(Expr)) {
4455 reportParseError("expected expression");
4459 if (Expr->getKind() != MCExpr::SymbolRef) {
4460 reportParseError("expected symbol");
4463 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4465 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4470 bool MipsAsmParser::parseDirectiveNaN() {
4471 MCAsmParser &Parser = getParser();
4472 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4473 const AsmToken &Tok = Parser.getTok();
4475 if (Tok.getString() == "2008") {
4477 getTargetStreamer().emitDirectiveNaN2008();
4479 } else if (Tok.getString() == "legacy") {
4481 getTargetStreamer().emitDirectiveNaNLegacy();
4485 // If we don't recognize the option passed to the .nan
4486 // directive (e.g. no option or unknown option), emit an error.
4487 reportParseError("invalid option in .nan directive");
4491 bool MipsAsmParser::parseDirectiveSet() {
4492 MCAsmParser &Parser = getParser();
4493 // Get the next token.
4494 const AsmToken &Tok = Parser.getTok();
4496 if (Tok.getString() == "noat") {
4497 return parseSetNoAtDirective();
4498 } else if (Tok.getString() == "at") {
4499 return parseSetAtDirective();
4500 } else if (Tok.getString() == "arch") {
4501 return parseSetArchDirective();
4502 } else if (Tok.getString() == "fp") {
4503 return parseSetFpDirective();
4504 } else if (Tok.getString() == "oddspreg") {
4505 return parseSetOddSPRegDirective();
4506 } else if (Tok.getString() == "nooddspreg") {
4507 return parseSetNoOddSPRegDirective();
4508 } else if (Tok.getString() == "pop") {
4509 return parseSetPopDirective();
4510 } else if (Tok.getString() == "push") {
4511 return parseSetPushDirective();
4512 } else if (Tok.getString() == "reorder") {
4513 return parseSetReorderDirective();
4514 } else if (Tok.getString() == "noreorder") {
4515 return parseSetNoReorderDirective();
4516 } else if (Tok.getString() == "macro") {
4517 return parseSetMacroDirective();
4518 } else if (Tok.getString() == "nomacro") {
4519 return parseSetNoMacroDirective();
4520 } else if (Tok.getString() == "mips16") {
4521 return parseSetMips16Directive();
4522 } else if (Tok.getString() == "nomips16") {
4523 return parseSetNoMips16Directive();
4524 } else if (Tok.getString() == "nomicromips") {
4525 getTargetStreamer().emitDirectiveSetNoMicroMips();
4526 Parser.eatToEndOfStatement();
4528 } else if (Tok.getString() == "micromips") {
4529 return parseSetFeature(Mips::FeatureMicroMips);
4530 } else if (Tok.getString() == "mips0") {
4531 return parseSetMips0Directive();
4532 } else if (Tok.getString() == "mips1") {
4533 return parseSetFeature(Mips::FeatureMips1);
4534 } else if (Tok.getString() == "mips2") {
4535 return parseSetFeature(Mips::FeatureMips2);
4536 } else if (Tok.getString() == "mips3") {
4537 return parseSetFeature(Mips::FeatureMips3);
4538 } else if (Tok.getString() == "mips4") {
4539 return parseSetFeature(Mips::FeatureMips4);
4540 } else if (Tok.getString() == "mips5") {
4541 return parseSetFeature(Mips::FeatureMips5);
4542 } else if (Tok.getString() == "mips32") {
4543 return parseSetFeature(Mips::FeatureMips32);
4544 } else if (Tok.getString() == "mips32r2") {
4545 return parseSetFeature(Mips::FeatureMips32r2);
4546 } else if (Tok.getString() == "mips32r3") {
4547 return parseSetFeature(Mips::FeatureMips32r3);
4548 } else if (Tok.getString() == "mips32r5") {
4549 return parseSetFeature(Mips::FeatureMips32r5);
4550 } else if (Tok.getString() == "mips32r6") {
4551 return parseSetFeature(Mips::FeatureMips32r6);
4552 } else if (Tok.getString() == "mips64") {
4553 return parseSetFeature(Mips::FeatureMips64);
4554 } else if (Tok.getString() == "mips64r2") {
4555 return parseSetFeature(Mips::FeatureMips64r2);
4556 } else if (Tok.getString() == "mips64r3") {
4557 return parseSetFeature(Mips::FeatureMips64r3);
4558 } else if (Tok.getString() == "mips64r5") {
4559 return parseSetFeature(Mips::FeatureMips64r5);
4560 } else if (Tok.getString() == "mips64r6") {
4561 return parseSetFeature(Mips::FeatureMips64r6);
4562 } else if (Tok.getString() == "dsp") {
4563 return parseSetFeature(Mips::FeatureDSP);
4564 } else if (Tok.getString() == "nodsp") {
4565 return parseSetNoDspDirective();
4566 } else if (Tok.getString() == "msa") {
4567 return parseSetMsaDirective();
4568 } else if (Tok.getString() == "nomsa") {
4569 return parseSetNoMsaDirective();
4570 } else if (Tok.getString() == "softfloat") {
4571 return parseSetSoftFloatDirective();
4572 } else if (Tok.getString() == "hardfloat") {
4573 return parseSetHardFloatDirective();
4575 // It is just an identifier, look for an assignment.
4576 parseSetAssignment();
4583 /// parseDataDirective
4584 /// ::= .word [ expression (, expression)* ]
4585 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4586 MCAsmParser &Parser = getParser();
4587 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4589 const MCExpr *Value;
4590 if (getParser().parseExpression(Value))
4593 getParser().getStreamer().EmitValue(Value, Size);
4595 if (getLexer().is(AsmToken::EndOfStatement))
4598 if (getLexer().isNot(AsmToken::Comma))
4599 return Error(L, "unexpected token, expected comma");
4608 /// parseDirectiveGpWord
4609 /// ::= .gpword local_sym
4610 bool MipsAsmParser::parseDirectiveGpWord() {
4611 MCAsmParser &Parser = getParser();
4612 const MCExpr *Value;
4613 // EmitGPRel32Value requires an expression, so we are using base class
4614 // method to evaluate the expression.
4615 if (getParser().parseExpression(Value))
4617 getParser().getStreamer().EmitGPRel32Value(Value);
4619 if (getLexer().isNot(AsmToken::EndOfStatement))
4620 return Error(getLexer().getLoc(),
4621 "unexpected token, expected end of statement");
4622 Parser.Lex(); // Eat EndOfStatement token.
4626 /// parseDirectiveGpDWord
4627 /// ::= .gpdword local_sym
4628 bool MipsAsmParser::parseDirectiveGpDWord() {
4629 MCAsmParser &Parser = getParser();
4630 const MCExpr *Value;
4631 // EmitGPRel64Value requires an expression, so we are using base class
4632 // method to evaluate the expression.
4633 if (getParser().parseExpression(Value))
4635 getParser().getStreamer().EmitGPRel64Value(Value);
4637 if (getLexer().isNot(AsmToken::EndOfStatement))
4638 return Error(getLexer().getLoc(),
4639 "unexpected token, expected end of statement");
4640 Parser.Lex(); // Eat EndOfStatement token.
4644 bool MipsAsmParser::parseDirectiveOption() {
4645 MCAsmParser &Parser = getParser();
4646 // Get the option token.
4647 AsmToken Tok = Parser.getTok();
4648 // At the moment only identifiers are supported.
4649 if (Tok.isNot(AsmToken::Identifier)) {
4650 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4651 Parser.eatToEndOfStatement();
4655 StringRef Option = Tok.getIdentifier();
4657 if (Option == "pic0") {
4658 getTargetStreamer().emitDirectiveOptionPic0();
4660 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4661 Error(Parser.getTok().getLoc(),
4662 "unexpected token, expected end of statement");
4663 Parser.eatToEndOfStatement();
4668 if (Option == "pic2") {
4669 getTargetStreamer().emitDirectiveOptionPic2();
4671 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4672 Error(Parser.getTok().getLoc(),
4673 "unexpected token, expected end of statement");
4674 Parser.eatToEndOfStatement();
4680 Warning(Parser.getTok().getLoc(),
4681 "unknown option, expected 'pic0' or 'pic2'");
4682 Parser.eatToEndOfStatement();
4686 /// parseInsnDirective
4688 bool MipsAsmParser::parseInsnDirective() {
4689 // If this is not the end of the statement, report an error.
4690 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4691 reportParseError("unexpected token, expected end of statement");
4695 // The actual label marking happens in
4696 // MipsELFStreamer::createPendingLabelRelocs().
4697 getTargetStreamer().emitDirectiveInsn();
4699 getParser().Lex(); // Eat EndOfStatement token.
4703 /// parseDirectiveModule
4704 /// ::= .module oddspreg
4705 /// ::= .module nooddspreg
4706 /// ::= .module fp=value
4707 /// ::= .module softfloat
4708 /// ::= .module hardfloat
4709 bool MipsAsmParser::parseDirectiveModule() {
4710 MCAsmParser &Parser = getParser();
4711 MCAsmLexer &Lexer = getLexer();
4712 SMLoc L = Lexer.getLoc();
4714 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4715 // TODO : get a better message.
4716 reportParseError(".module directive must appear before any code");
4721 if (Parser.parseIdentifier(Option)) {
4722 reportParseError("expected .module option identifier");
4726 if (Option == "oddspreg") {
4727 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4729 // Synchronize the abiflags information with the FeatureBits information we
4731 getTargetStreamer().updateABIInfo(*this);
4733 // If printing assembly, use the recently updated abiflags information.
4734 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4735 // emitted at the end).
4736 getTargetStreamer().emitDirectiveModuleOddSPReg();
4738 // If this is not the end of the statement, report an error.
4739 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4740 reportParseError("unexpected token, expected end of statement");
4744 return false; // parseDirectiveModule has finished successfully.
4745 } else if (Option == "nooddspreg") {
4747 Error(L, "'.module nooddspreg' requires the O32 ABI");
4751 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4753 // Synchronize the abiflags information with the FeatureBits information we
4755 getTargetStreamer().updateABIInfo(*this);
4757 // If printing assembly, use the recently updated abiflags information.
4758 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4759 // emitted at the end).
4760 getTargetStreamer().emitDirectiveModuleOddSPReg();
4762 // If this is not the end of the statement, report an error.
4763 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4764 reportParseError("unexpected token, expected end of statement");
4768 return false; // parseDirectiveModule has finished successfully.
4769 } else if (Option == "fp") {
4770 return parseDirectiveModuleFP();
4771 } else if (Option == "softfloat") {
4772 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4774 // Synchronize the ABI Flags information with the FeatureBits information we
4776 getTargetStreamer().updateABIInfo(*this);
4778 // If printing assembly, use the recently updated ABI Flags information.
4779 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4781 getTargetStreamer().emitDirectiveModuleSoftFloat();
4783 // If this is not the end of the statement, report an error.
4784 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4785 reportParseError("unexpected token, expected end of statement");
4789 return false; // parseDirectiveModule has finished successfully.
4790 } else if (Option == "hardfloat") {
4791 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4793 // Synchronize the ABI Flags information with the FeatureBits information we
4795 getTargetStreamer().updateABIInfo(*this);
4797 // If printing assembly, use the recently updated ABI Flags information.
4798 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4800 getTargetStreamer().emitDirectiveModuleHardFloat();
4802 // If this is not the end of the statement, report an error.
4803 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4804 reportParseError("unexpected token, expected end of statement");
4808 return false; // parseDirectiveModule has finished successfully.
4810 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4814 /// parseDirectiveModuleFP
4818 bool MipsAsmParser::parseDirectiveModuleFP() {
4819 MCAsmParser &Parser = getParser();
4820 MCAsmLexer &Lexer = getLexer();
4822 if (Lexer.isNot(AsmToken::Equal)) {
4823 reportParseError("unexpected token, expected equals sign '='");
4826 Parser.Lex(); // Eat '=' token.
4828 MipsABIFlagsSection::FpABIKind FpABI;
4829 if (!parseFpABIValue(FpABI, ".module"))
4832 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4833 reportParseError("unexpected token, expected end of statement");
4837 // Synchronize the abiflags information with the FeatureBits information we
4839 getTargetStreamer().updateABIInfo(*this);
4841 // If printing assembly, use the recently updated abiflags information.
4842 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4843 // emitted at the end).
4844 getTargetStreamer().emitDirectiveModuleFP();
4846 Parser.Lex(); // Consume the EndOfStatement.
4850 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4851 StringRef Directive) {
4852 MCAsmParser &Parser = getParser();
4853 MCAsmLexer &Lexer = getLexer();
4854 bool ModuleLevelOptions = Directive == ".module";
4856 if (Lexer.is(AsmToken::Identifier)) {
4857 StringRef Value = Parser.getTok().getString();
4860 if (Value != "xx") {
4861 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4866 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4870 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4871 if (ModuleLevelOptions) {
4872 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4873 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4875 setFeatureBits(Mips::FeatureFPXX, "fpxx");
4876 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4881 if (Lexer.is(AsmToken::Integer)) {
4882 unsigned Value = Parser.getTok().getIntVal();
4885 if (Value != 32 && Value != 64) {
4886 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4892 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4896 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4897 if (ModuleLevelOptions) {
4898 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4899 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4901 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4902 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4905 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4906 if (ModuleLevelOptions) {
4907 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4908 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4910 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4911 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
4921 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4922 MCAsmParser &Parser = getParser();
4923 StringRef IDVal = DirectiveID.getString();
4925 if (IDVal == ".cpload")
4926 return parseDirectiveCpLoad(DirectiveID.getLoc());
4927 if (IDVal == ".dword") {
4928 parseDataDirective(8, DirectiveID.getLoc());
4931 if (IDVal == ".ent") {
4932 StringRef SymbolName;
4934 if (Parser.parseIdentifier(SymbolName)) {
4935 reportParseError("expected identifier after .ent");
4939 // There's an undocumented extension that allows an integer to
4940 // follow the name of the procedure which AFAICS is ignored by GAS.
4941 // Example: .ent foo,2
4942 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4943 if (getLexer().isNot(AsmToken::Comma)) {
4944 // Even though we accept this undocumented extension for compatibility
4945 // reasons, the additional integer argument does not actually change
4946 // the behaviour of the '.ent' directive, so we would like to discourage
4947 // its use. We do this by not referring to the extended version in
4948 // error messages which are not directly related to its use.
4949 reportParseError("unexpected token, expected end of statement");
4952 Parser.Lex(); // Eat the comma.
4953 const MCExpr *DummyNumber;
4954 int64_t DummyNumberVal;
4955 // If the user was explicitly trying to use the extended version,
4956 // we still give helpful extension-related error messages.
4957 if (Parser.parseExpression(DummyNumber)) {
4958 reportParseError("expected number after comma");
4961 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4962 reportParseError("expected an absolute expression after comma");
4967 // If this is not the end of the statement, report an error.
4968 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4969 reportParseError("unexpected token, expected end of statement");
4973 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4975 getTargetStreamer().emitDirectiveEnt(*Sym);
4980 if (IDVal == ".end") {
4981 StringRef SymbolName;
4983 if (Parser.parseIdentifier(SymbolName)) {
4984 reportParseError("expected identifier after .end");
4988 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4989 reportParseError("unexpected token, expected end of statement");
4993 if (CurrentFn == nullptr) {
4994 reportParseError(".end used without .ent");
4998 if ((SymbolName != CurrentFn->getName())) {
4999 reportParseError(".end symbol does not match .ent symbol");
5003 getTargetStreamer().emitDirectiveEnd(SymbolName);
5004 CurrentFn = nullptr;
5008 if (IDVal == ".frame") {
5009 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5010 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5011 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5012 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5013 reportParseError("expected stack register");
5017 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5018 if (!StackRegOpnd.isGPRAsmReg()) {
5019 reportParseError(StackRegOpnd.getStartLoc(),
5020 "expected general purpose register");
5023 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5025 if (Parser.getTok().is(AsmToken::Comma))
5028 reportParseError("unexpected token, expected comma");
5032 // Parse the frame size.
5033 const MCExpr *FrameSize;
5034 int64_t FrameSizeVal;
5036 if (Parser.parseExpression(FrameSize)) {
5037 reportParseError("expected frame size value");
5041 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5042 reportParseError("frame size not an absolute expression");
5046 if (Parser.getTok().is(AsmToken::Comma))
5049 reportParseError("unexpected token, expected comma");
5053 // Parse the return register.
5055 ResTy = parseAnyRegister(TmpReg);
5056 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5057 reportParseError("expected return register");
5061 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5062 if (!ReturnRegOpnd.isGPRAsmReg()) {
5063 reportParseError(ReturnRegOpnd.getStartLoc(),
5064 "expected general purpose register");
5068 // If this is not the end of the statement, report an error.
5069 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5070 reportParseError("unexpected token, expected end of statement");
5074 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5075 ReturnRegOpnd.getGPR32Reg());
5079 if (IDVal == ".set") {
5080 return parseDirectiveSet();
5083 if (IDVal == ".mask" || IDVal == ".fmask") {
5084 // .mask bitmask, frame_offset
5085 // bitmask: One bit for each register used.
5086 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5087 // first register is expected to be saved.
5089 // .mask 0x80000000, -4
5090 // .fmask 0x80000000, -4
5093 // Parse the bitmask
5094 const MCExpr *BitMask;
5097 if (Parser.parseExpression(BitMask)) {
5098 reportParseError("expected bitmask value");
5102 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5103 reportParseError("bitmask not an absolute expression");
5107 if (Parser.getTok().is(AsmToken::Comma))
5110 reportParseError("unexpected token, expected comma");
5114 // Parse the frame_offset
5115 const MCExpr *FrameOffset;
5116 int64_t FrameOffsetVal;
5118 if (Parser.parseExpression(FrameOffset)) {
5119 reportParseError("expected frame offset value");
5123 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5124 reportParseError("frame offset not an absolute expression");
5128 // If this is not the end of the statement, report an error.
5129 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5130 reportParseError("unexpected token, expected end of statement");
5134 if (IDVal == ".mask")
5135 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5137 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5141 if (IDVal == ".nan")
5142 return parseDirectiveNaN();
5144 if (IDVal == ".gpword") {
5145 parseDirectiveGpWord();
5149 if (IDVal == ".gpdword") {
5150 parseDirectiveGpDWord();
5154 if (IDVal == ".word") {
5155 parseDataDirective(4, DirectiveID.getLoc());
5159 if (IDVal == ".option")
5160 return parseDirectiveOption();
5162 if (IDVal == ".abicalls") {
5163 getTargetStreamer().emitDirectiveAbiCalls();
5164 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5165 Error(Parser.getTok().getLoc(),
5166 "unexpected token, expected end of statement");
5168 Parser.eatToEndOfStatement();
5173 if (IDVal == ".cpsetup")
5174 return parseDirectiveCPSetup();
5176 if (IDVal == ".module")
5177 return parseDirectiveModule();
5179 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5180 return parseInternalDirectiveReallowModule();
5182 if (IDVal == ".insn")
5183 return parseInsnDirective();
5188 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5189 // If this is not the end of the statement, report an error.
5190 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5191 reportParseError("unexpected token, expected end of statement");
5195 getTargetStreamer().reallowModuleDirective();
5197 getParser().Lex(); // Eat EndOfStatement token.
5201 extern "C" void LLVMInitializeMipsAsmParser() {
5202 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5203 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5204 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5205 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5208 #define GET_REGISTER_MATCHER
5209 #define GET_MATCHER_IMPLEMENTATION
5210 #include "MipsGenAsmMatcher.inc"