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"
36 #define DEBUG_TYPE "mips-asm-parser"
43 class MipsAssemblerOptions {
45 MipsAssemblerOptions(uint64_t Features_) :
46 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
48 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
49 ATReg = Opts->getATRegNum();
50 Reorder = Opts->isReorder();
51 Macro = Opts->isMacro();
52 Features = Opts->getFeatures();
55 unsigned getATRegNum() const { return ATReg; }
56 bool setATReg(unsigned Reg);
58 bool isReorder() const { return Reorder; }
59 void setReorder() { Reorder = true; }
60 void setNoReorder() { Reorder = false; }
62 bool isMacro() const { return Macro; }
63 void setMacro() { Macro = true; }
64 void setNoMacro() { Macro = false; }
66 uint64_t getFeatures() const { return Features; }
67 void setFeatures(uint64_t Features_) { Features = Features_; }
69 // Set of features that are either architecture features or referenced
70 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
71 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
72 // The reason we need this mask is explained in the selectArch function.
73 // FIXME: Ideally we would like TableGen to generate this information.
74 static const uint64_t AllArchRelatedMask =
75 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
76 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
77 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
78 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
79 Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
80 Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
81 Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
82 Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
93 class MipsAsmParser : public MCTargetAsmParser {
94 MipsTargetStreamer &getTargetStreamer() {
95 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
96 return static_cast<MipsTargetStreamer &>(TS);
101 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
102 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
103 // nullptr, which indicates that no function is currently
104 // selected. This usually happens after an '.end func'
107 // Print a warning along with its fix-it message at the given range.
108 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
109 SMRange Range, bool ShowColors = true);
111 #define GET_ASSEMBLER_HEADER
112 #include "MipsGenAsmMatcher.inc"
114 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
116 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
117 OperandVector &Operands, MCStreamer &Out,
119 bool MatchingInlineAsm) override;
121 /// Parse a register as used in CFI directives
122 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
124 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
126 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
128 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
129 SMLoc NameLoc, OperandVector &Operands) override;
131 bool ParseDirective(AsmToken DirectiveID) override;
133 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
135 MipsAsmParser::OperandMatchResultTy
136 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
137 StringRef Identifier, SMLoc S);
139 MipsAsmParser::OperandMatchResultTy
140 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
142 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
144 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
146 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
148 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
150 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
152 MipsAsmParser::OperandMatchResultTy
153 parseRegisterPair (OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy
156 parseMovePRegPair(OperandVector &Operands);
158 MipsAsmParser::OperandMatchResultTy
159 parseRegisterList (OperandVector &Operands);
161 bool searchSymbolAlias(OperandVector &Operands);
163 bool parseOperand(OperandVector &, StringRef Mnemonic);
165 bool needsExpansion(MCInst &Inst);
167 // Expands assembly pseudo instructions.
168 // Returns false on success, true otherwise.
169 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
170 SmallVectorImpl<MCInst> &Instructions);
172 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
173 SmallVectorImpl<MCInst> &Instructions);
175 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
176 SmallVectorImpl<MCInst> &Instructions);
178 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
179 SmallVectorImpl<MCInst> &Instructions);
181 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
182 SmallVectorImpl<MCInst> &Instructions);
183 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
186 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
187 SmallVectorImpl<MCInst> &Instructions);
189 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
193 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 bool reportParseError(Twine ErrorMsg);
197 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
199 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
200 bool parseRelocOperand(const MCExpr *&Res);
202 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
204 bool isEvaluated(const MCExpr *Expr);
205 bool parseSetMips0Directive();
206 bool parseSetArchDirective();
207 bool parseSetFeature(uint64_t Feature);
208 bool parseDirectiveCpLoad(SMLoc Loc);
209 bool parseDirectiveCPSetup();
210 bool parseDirectiveNaN();
211 bool parseDirectiveSet();
212 bool parseDirectiveOption();
214 bool parseSetAtDirective();
215 bool parseSetNoAtDirective();
216 bool parseSetMacroDirective();
217 bool parseSetNoMacroDirective();
218 bool parseSetMsaDirective();
219 bool parseSetNoMsaDirective();
220 bool parseSetNoDspDirective();
221 bool parseSetReorderDirective();
222 bool parseSetNoReorderDirective();
223 bool parseSetMips16Directive();
224 bool parseSetNoMips16Directive();
225 bool parseSetFpDirective();
226 bool parseSetPopDirective();
227 bool parseSetPushDirective();
229 bool parseSetAssignment();
231 bool parseDataDirective(unsigned Size, SMLoc L);
232 bool parseDirectiveGpWord();
233 bool parseDirectiveGpDWord();
234 bool parseDirectiveModule();
235 bool parseDirectiveModuleFP();
236 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
237 StringRef Directive);
239 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
241 bool eatComma(StringRef ErrorStr);
243 int matchCPURegisterName(StringRef Symbol);
245 int matchHWRegsRegisterName(StringRef Symbol);
247 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
249 int matchFPURegisterName(StringRef Name);
251 int matchFCCRegisterName(StringRef Name);
253 int matchACRegisterName(StringRef Name);
255 int matchMSA128RegisterName(StringRef Name);
257 int matchMSA128CtrlRegisterName(StringRef Name);
259 unsigned getReg(int RC, int RegNo);
261 unsigned getGPR(int RegNo);
263 int getATReg(SMLoc Loc);
265 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
266 SmallVectorImpl<MCInst> &Instructions);
268 // Helper function that checks if the value of a vector index is within the
269 // boundaries of accepted values for each RegisterKind
270 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
271 bool validateMSAIndex(int Val, int RegKind);
273 // Selects a new architecture by updating the FeatureBits with the necessary
274 // info including implied dependencies.
275 // Internally, it clears all the feature bits related to *any* architecture
276 // and selects the new one using the ToggleFeature functionality of the
277 // MCSubtargetInfo object that handles implied dependencies. The reason we
278 // clear all the arch related bits manually is because ToggleFeature only
279 // clears the features that imply the feature being cleared and not the
280 // features implied by the feature being cleared. This is easier to see
282 // --------------------------------------------------
283 // | Feature | Implies |
284 // | -------------------------------------------------|
285 // | FeatureMips1 | None |
286 // | FeatureMips2 | FeatureMips1 |
287 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
288 // | FeatureMips4 | FeatureMips3 |
290 // --------------------------------------------------
292 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
293 // FeatureMipsGP64 | FeatureMips1)
294 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
295 void selectArch(StringRef ArchFeature) {
296 uint64_t FeatureBits = STI.getFeatureBits();
297 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
298 STI.setFeatureBits(FeatureBits);
299 setAvailableFeatures(
300 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
301 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
304 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
305 if (!(STI.getFeatureBits() & Feature)) {
306 setAvailableFeatures(
307 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
309 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
312 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
313 if (STI.getFeatureBits() & Feature) {
314 setAvailableFeatures(
315 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
317 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
321 enum MipsMatchResultTy {
322 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
323 #define GET_OPERAND_DIAGNOSTIC_TYPES
324 #include "MipsGenAsmMatcher.inc"
325 #undef GET_OPERAND_DIAGNOSTIC_TYPES
329 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
330 const MCInstrInfo &MII, const MCTargetOptions &Options)
331 : MCTargetAsmParser(), STI(sti),
332 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
333 sti.getCPU(), Options)) {
334 MCAsmParserExtension::Initialize(parser);
336 // Initialize the set of available features.
337 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
339 // Remember the initial assembler options. The user can not modify these.
340 AssemblerOptions.push_back(
341 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
343 // Create an assembler options environment for the user to modify.
344 AssemblerOptions.push_back(
345 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
347 getTargetStreamer().updateABIInfo(*this);
349 if (!isABI_O32() && !useOddSPReg() != 0)
350 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
355 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
356 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
358 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
359 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
360 const MipsABIInfo &getABI() const { return ABI; }
361 bool isABI_N32() const { return ABI.IsN32(); }
362 bool isABI_N64() const { return ABI.IsN64(); }
363 bool isABI_O32() const { return ABI.IsO32(); }
364 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
366 bool useOddSPReg() const {
367 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
370 bool inMicroMipsMode() const {
371 return STI.getFeatureBits() & Mips::FeatureMicroMips;
373 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
374 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
375 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
376 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
377 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
378 bool hasMips32() const {
379 return (STI.getFeatureBits() & Mips::FeatureMips32);
381 bool hasMips64() const {
382 return (STI.getFeatureBits() & Mips::FeatureMips64);
384 bool hasMips32r2() const {
385 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
387 bool hasMips64r2() const {
388 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
390 bool hasMips32r3() const {
391 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
393 bool hasMips64r3() const {
394 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
396 bool hasMips32r5() const {
397 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
399 bool hasMips64r5() const {
400 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
402 bool hasMips32r6() const {
403 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
405 bool hasMips64r6() const {
406 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
408 bool hasCnMips() const {
409 return (STI.getFeatureBits() & Mips::FeatureCnMips);
411 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
412 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
413 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
415 bool inMips16Mode() const {
416 return STI.getFeatureBits() & Mips::FeatureMips16;
418 // TODO: see how can we get this info.
419 bool abiUsesSoftFloat() const { return false; }
421 /// Warn if RegNo is the current assembler temporary.
422 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
428 /// MipsOperand - Instances of this class represent a parsed Mips machine
430 class MipsOperand : public MCParsedAsmOperand {
432 /// Broad categories of register classes
433 /// The exact class is finalized by the render method.
435 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
436 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
438 RegKind_FCC = 4, /// FCC
439 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
440 RegKind_MSACtrl = 16, /// MSA control registers
441 RegKind_COP2 = 32, /// COP2
442 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
444 RegKind_CCR = 128, /// CCR
445 RegKind_HWRegs = 256, /// HWRegs
446 RegKind_COP3 = 512, /// COP3
448 /// Potentially any (e.g. $1)
449 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
450 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
451 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
456 k_Immediate, /// An immediate (possibly involving symbol references)
457 k_Memory, /// Base + Offset Memory Address
458 k_PhysRegister, /// A physical register from the Mips namespace
459 k_RegisterIndex, /// A register index in one or more RegKind.
460 k_Token, /// A simple token
461 k_RegList, /// A physical register list
462 k_RegPair /// A pair of physical register
466 MipsOperand(KindTy K, MipsAsmParser &Parser)
467 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
470 /// For diagnostics, and checking the assembler temporary
471 MipsAsmParser &AsmParser;
479 unsigned Num; /// Register Number
483 unsigned Index; /// Index into the register class
484 RegKind Kind; /// Bitfield of the kinds it could possibly be
485 const MCRegisterInfo *RegInfo;
498 SmallVector<unsigned, 10> *List;
503 struct PhysRegOp PhysReg;
504 struct RegIdxOp RegIdx;
507 struct RegListOp RegList;
510 SMLoc StartLoc, EndLoc;
512 /// Internal constructor for register kinds
513 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
514 const MCRegisterInfo *RegInfo,
516 MipsAsmParser &Parser) {
517 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
518 Op->RegIdx.Index = Index;
519 Op->RegIdx.RegInfo = RegInfo;
520 Op->RegIdx.Kind = RegKind;
527 /// Coerce the register to GPR32 and return the real register for the current
529 unsigned getGPR32Reg() const {
530 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
531 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
532 unsigned ClassID = Mips::GPR32RegClassID;
533 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
536 /// Coerce the register to GPR32 and return the real register for the current
538 unsigned getGPRMM16Reg() const {
539 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
540 unsigned ClassID = Mips::GPR32RegClassID;
541 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
544 /// Coerce the register to GPR64 and return the real register for the current
546 unsigned getGPR64Reg() const {
547 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
548 unsigned ClassID = Mips::GPR64RegClassID;
549 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
553 /// Coerce the register to AFGR64 and return the real register for the current
555 unsigned getAFGR64Reg() const {
556 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
557 if (RegIdx.Index % 2 != 0)
558 AsmParser.Warning(StartLoc, "Float register should be even.");
559 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
560 .getRegister(RegIdx.Index / 2);
563 /// Coerce the register to FGR64 and return the real register for the current
565 unsigned getFGR64Reg() const {
566 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
567 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
568 .getRegister(RegIdx.Index);
571 /// Coerce the register to FGR32 and return the real register for the current
573 unsigned getFGR32Reg() const {
574 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
575 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
576 .getRegister(RegIdx.Index);
579 /// Coerce the register to FGRH32 and return the real register for the current
581 unsigned getFGRH32Reg() const {
582 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
583 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
584 .getRegister(RegIdx.Index);
587 /// Coerce the register to FCC and return the real register for the current
589 unsigned getFCCReg() const {
590 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
591 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
592 .getRegister(RegIdx.Index);
595 /// Coerce the register to MSA128 and return the real register for the current
597 unsigned getMSA128Reg() const {
598 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
599 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
601 unsigned ClassID = Mips::MSA128BRegClassID;
602 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
605 /// Coerce the register to MSACtrl and return the real register for the
607 unsigned getMSACtrlReg() const {
608 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
609 unsigned ClassID = Mips::MSACtrlRegClassID;
610 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
613 /// Coerce the register to COP2 and return the real register for the
615 unsigned getCOP2Reg() const {
616 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
617 unsigned ClassID = Mips::COP2RegClassID;
618 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
621 /// Coerce the register to COP3 and return the real register for the
623 unsigned getCOP3Reg() const {
624 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
625 unsigned ClassID = Mips::COP3RegClassID;
626 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
629 /// Coerce the register to ACC64DSP and return the real register for the
631 unsigned getACC64DSPReg() const {
632 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
633 unsigned ClassID = Mips::ACC64DSPRegClassID;
634 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
637 /// Coerce the register to HI32DSP and return the real register for the
639 unsigned getHI32DSPReg() const {
640 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
641 unsigned ClassID = Mips::HI32DSPRegClassID;
642 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
645 /// Coerce the register to LO32DSP and return the real register for the
647 unsigned getLO32DSPReg() const {
648 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
649 unsigned ClassID = Mips::LO32DSPRegClassID;
650 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
653 /// Coerce the register to CCR and return the real register for the
655 unsigned getCCRReg() const {
656 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
657 unsigned ClassID = Mips::CCRRegClassID;
658 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
661 /// Coerce the register to HWRegs and return the real register for the
663 unsigned getHWRegsReg() const {
664 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
665 unsigned ClassID = Mips::HWRegsRegClassID;
666 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
670 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
671 // Add as immediate when possible. Null MCExpr = 0.
673 Inst.addOperand(MCOperand::CreateImm(0));
674 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
675 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
677 Inst.addOperand(MCOperand::CreateExpr(Expr));
680 void addRegOperands(MCInst &Inst, unsigned N) const {
681 llvm_unreachable("Use a custom parser instead");
684 /// Render the operand to an MCInst as a GPR32
685 /// Asserts if the wrong number of operands are requested, or the operand
686 /// is not a k_RegisterIndex compatible with RegKind_GPR
687 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
688 assert(N == 1 && "Invalid number of operands!");
689 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
692 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
693 assert(N == 1 && "Invalid number of operands!");
694 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
697 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
698 assert(N == 1 && "Invalid number of operands!");
699 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
702 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
703 assert(N == 1 && "Invalid number of operands!");
704 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
707 /// Render the operand to an MCInst as a GPR64
708 /// Asserts if the wrong number of operands are requested, or the operand
709 /// is not a k_RegisterIndex compatible with RegKind_GPR
710 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
711 assert(N == 1 && "Invalid number of operands!");
712 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
715 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
716 assert(N == 1 && "Invalid number of operands!");
717 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
720 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
721 assert(N == 1 && "Invalid number of operands!");
722 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
725 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
726 assert(N == 1 && "Invalid number of operands!");
727 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
728 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
729 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
730 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
734 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
735 assert(N == 1 && "Invalid number of operands!");
736 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
739 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
740 assert(N == 1 && "Invalid number of operands!");
741 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
744 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
745 assert(N == 1 && "Invalid number of operands!");
746 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
749 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
754 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
759 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
764 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
765 assert(N == 1 && "Invalid number of operands!");
766 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
769 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
770 assert(N == 1 && "Invalid number of operands!");
771 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
774 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
775 assert(N == 1 && "Invalid number of operands!");
776 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
779 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
780 assert(N == 1 && "Invalid number of operands!");
781 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
784 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
785 assert(N == 1 && "Invalid number of operands!");
786 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
789 void addImmOperands(MCInst &Inst, unsigned N) const {
790 assert(N == 1 && "Invalid number of operands!");
791 const MCExpr *Expr = getImm();
795 void addMemOperands(MCInst &Inst, unsigned N) const {
796 assert(N == 2 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
800 const MCExpr *Expr = getMemOff();
804 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
805 assert(N == 2 && "Invalid number of operands!");
807 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
809 const MCExpr *Expr = getMemOff();
813 void addRegListOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 1 && "Invalid number of operands!");
816 for (auto RegNo : getRegList())
817 Inst.addOperand(MCOperand::CreateReg(RegNo));
820 void addRegPairOperands(MCInst &Inst, unsigned N) const {
821 assert(N == 2 && "Invalid number of operands!");
822 unsigned RegNo = getRegPair();
823 Inst.addOperand(MCOperand::CreateReg(RegNo++));
824 Inst.addOperand(MCOperand::CreateReg(RegNo));
827 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
828 assert(N == 2 && "Invalid number of operands!");
829 for (auto RegNo : getRegList())
830 Inst.addOperand(MCOperand::CreateReg(RegNo));
833 bool isReg() const override {
834 // As a special case until we sort out the definition of div/divu, pretend
835 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
836 if (isGPRAsmReg() && RegIdx.Index == 0)
839 return Kind == k_PhysRegister;
841 bool isRegIdx() const { return Kind == k_RegisterIndex; }
842 bool isImm() const override { return Kind == k_Immediate; }
843 bool isConstantImm() const {
844 return isImm() && dyn_cast<MCConstantExpr>(getImm());
846 bool isToken() const override {
847 // Note: It's not possible to pretend that other operand kinds are tokens.
848 // The matcher emitter checks tokens first.
849 return Kind == k_Token;
851 bool isMem() const override { return Kind == k_Memory; }
852 bool isConstantMemOff() const {
853 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
855 template <unsigned Bits> bool isMemWithSimmOffset() const {
856 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
858 bool isMemWithGRPMM16Base() const {
859 return isMem() && getMemBase()->isMM16AsmReg();
861 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
862 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
863 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
865 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
866 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
867 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
868 && (getMemBase()->getGPR32Reg() == Mips::SP);
870 bool isRegList16() const {
874 int Size = RegList.List->size();
875 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
876 RegList.List->back() != Mips::RA)
879 int PrevReg = *RegList.List->begin();
880 for (int i = 1; i < Size - 1; i++) {
881 int Reg = (*(RegList.List))[i];
882 if ( Reg != PrevReg + 1)
889 bool isInvNum() const { return Kind == k_Immediate; }
890 bool isLSAImm() const {
891 if (!isConstantImm())
893 int64_t Val = getConstantImm();
894 return 1 <= Val && Val <= 4;
896 bool isRegList() const { return Kind == k_RegList; }
897 bool isMovePRegPair() const {
898 if (Kind != k_RegList || RegList.List->size() != 2)
901 unsigned R0 = RegList.List->front();
902 unsigned R1 = RegList.List->back();
904 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
905 (R0 == Mips::A1 && R1 == Mips::A3) ||
906 (R0 == Mips::A2 && R1 == Mips::A3) ||
907 (R0 == Mips::A0 && R1 == Mips::S5) ||
908 (R0 == Mips::A0 && R1 == Mips::S6) ||
909 (R0 == Mips::A0 && R1 == Mips::A1) ||
910 (R0 == Mips::A0 && R1 == Mips::A2) ||
911 (R0 == Mips::A0 && R1 == Mips::A3))
917 StringRef getToken() const {
918 assert(Kind == k_Token && "Invalid access!");
919 return StringRef(Tok.Data, Tok.Length);
921 bool isRegPair() const { return Kind == k_RegPair; }
923 unsigned getReg() const override {
924 // As a special case until we sort out the definition of div/divu, pretend
925 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
926 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
927 RegIdx.Kind & RegKind_GPR)
928 return getGPR32Reg(); // FIXME: GPR64 too
930 assert(Kind == k_PhysRegister && "Invalid access!");
934 const MCExpr *getImm() const {
935 assert((Kind == k_Immediate) && "Invalid access!");
939 int64_t getConstantImm() const {
940 const MCExpr *Val = getImm();
941 return static_cast<const MCConstantExpr *>(Val)->getValue();
944 MipsOperand *getMemBase() const {
945 assert((Kind == k_Memory) && "Invalid access!");
949 const MCExpr *getMemOff() const {
950 assert((Kind == k_Memory) && "Invalid access!");
954 int64_t getConstantMemOff() const {
955 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
958 const SmallVectorImpl<unsigned> &getRegList() const {
959 assert((Kind == k_RegList) && "Invalid access!");
960 return *(RegList.List);
963 unsigned getRegPair() const {
964 assert((Kind == k_RegPair) && "Invalid access!");
968 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
969 MipsAsmParser &Parser) {
970 auto Op = make_unique<MipsOperand>(k_Token, Parser);
971 Op->Tok.Data = Str.data();
972 Op->Tok.Length = Str.size();
978 /// Create a numeric register (e.g. $1). The exact register remains
979 /// unresolved until an instruction successfully matches
980 static std::unique_ptr<MipsOperand>
981 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
982 SMLoc E, MipsAsmParser &Parser) {
983 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
984 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
987 /// Create a register that is definitely a GPR.
988 /// This is typically only used for named registers such as $gp.
989 static std::unique_ptr<MipsOperand>
990 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
991 MipsAsmParser &Parser) {
992 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
995 /// Create a register that is definitely a FGR.
996 /// This is typically only used for named registers such as $f0.
997 static std::unique_ptr<MipsOperand>
998 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
999 MipsAsmParser &Parser) {
1000 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1003 /// Create a register that is definitely a HWReg.
1004 /// This is typically only used for named registers such as $hwr_cpunum.
1005 static std::unique_ptr<MipsOperand>
1006 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1007 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1008 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1011 /// Create a register that is definitely an FCC.
1012 /// This is typically only used for named registers such as $fcc0.
1013 static std::unique_ptr<MipsOperand>
1014 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1015 MipsAsmParser &Parser) {
1016 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1019 /// Create a register that is definitely an ACC.
1020 /// This is typically only used for named registers such as $ac0.
1021 static std::unique_ptr<MipsOperand>
1022 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1023 MipsAsmParser &Parser) {
1024 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1027 /// Create a register that is definitely an MSA128.
1028 /// This is typically only used for named registers such as $w0.
1029 static std::unique_ptr<MipsOperand>
1030 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1031 SMLoc E, MipsAsmParser &Parser) {
1032 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1035 /// Create a register that is definitely an MSACtrl.
1036 /// This is typically only used for named registers such as $msaaccess.
1037 static std::unique_ptr<MipsOperand>
1038 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1039 SMLoc E, MipsAsmParser &Parser) {
1040 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1043 static std::unique_ptr<MipsOperand>
1044 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1045 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1052 static std::unique_ptr<MipsOperand>
1053 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1054 SMLoc E, MipsAsmParser &Parser) {
1055 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1056 Op->Mem.Base = Base.release();
1063 static std::unique_ptr<MipsOperand>
1064 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1065 MipsAsmParser &Parser) {
1066 assert (Regs.size() > 0 && "Empty list not allowed");
1068 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1069 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1070 Op->StartLoc = StartLoc;
1071 Op->EndLoc = EndLoc;
1075 static std::unique_ptr<MipsOperand>
1076 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1077 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1078 Op->RegIdx.Index = RegNo;
1084 bool isGPRAsmReg() const {
1085 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1087 bool isMM16AsmReg() const {
1088 if (!(isRegIdx() && RegIdx.Kind))
1090 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1091 || RegIdx.Index == 16 || RegIdx.Index == 17);
1093 bool isMM16AsmRegZero() const {
1094 if (!(isRegIdx() && RegIdx.Kind))
1096 return (RegIdx.Index == 0 ||
1097 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1098 RegIdx.Index == 17);
1100 bool isMM16AsmRegMoveP() const {
1101 if (!(isRegIdx() && RegIdx.Kind))
1103 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1104 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1106 bool isFGRAsmReg() const {
1107 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1108 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1110 bool isHWRegsAsmReg() const {
1111 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1113 bool isCCRAsmReg() const {
1114 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1116 bool isFCCAsmReg() const {
1117 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1119 if (!AsmParser.hasEightFccRegisters())
1120 return RegIdx.Index == 0;
1121 return RegIdx.Index <= 7;
1123 bool isACCAsmReg() const {
1124 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1126 bool isCOP2AsmReg() const {
1127 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1129 bool isCOP3AsmReg() const {
1130 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1132 bool isMSA128AsmReg() const {
1133 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1135 bool isMSACtrlAsmReg() const {
1136 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1139 /// getStartLoc - Get the location of the first token of this operand.
1140 SMLoc getStartLoc() const override { return StartLoc; }
1141 /// getEndLoc - Get the location of the last token of this operand.
1142 SMLoc getEndLoc() const override { return EndLoc; }
1144 virtual ~MipsOperand() {
1152 delete RegList.List;
1153 case k_PhysRegister:
1154 case k_RegisterIndex:
1161 void print(raw_ostream &OS) const override {
1170 Mem.Base->print(OS);
1175 case k_PhysRegister:
1176 OS << "PhysReg<" << PhysReg.Num << ">";
1178 case k_RegisterIndex:
1179 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1186 for (auto Reg : (*RegList.List))
1191 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1195 }; // class MipsOperand
1199 extern const MCInstrDesc MipsInsts[];
1201 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1202 return MipsInsts[Opcode];
1205 static bool hasShortDelaySlot(unsigned Opcode) {
1208 case Mips::JALRS_MM:
1209 case Mips::JALRS16_MM:
1210 case Mips::BGEZALS_MM:
1211 case Mips::BLTZALS_MM:
1218 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1219 SmallVectorImpl<MCInst> &Instructions) {
1220 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1224 if (MCID.isBranch() || MCID.isCall()) {
1225 const unsigned Opcode = Inst.getOpcode();
1235 assert(hasCnMips() && "instruction only valid for octeon cpus");
1242 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1243 Offset = Inst.getOperand(2);
1244 if (!Offset.isImm())
1245 break; // We'll deal with this situation later on when applying fixups.
1246 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1247 return Error(IDLoc, "branch target out of range");
1248 if (OffsetToAlignment(Offset.getImm(),
1249 1LL << (inMicroMipsMode() ? 1 : 2)))
1250 return Error(IDLoc, "branch to misaligned address");
1264 case Mips::BGEZAL_MM:
1265 case Mips::BLTZAL_MM:
1268 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1269 Offset = Inst.getOperand(1);
1270 if (!Offset.isImm())
1271 break; // We'll deal with this situation later on when applying fixups.
1272 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1273 return Error(IDLoc, "branch target out of range");
1274 if (OffsetToAlignment(Offset.getImm(),
1275 1LL << (inMicroMipsMode() ? 1 : 2)))
1276 return Error(IDLoc, "branch to misaligned address");
1278 case Mips::BEQZ16_MM:
1279 case Mips::BNEZ16_MM:
1280 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1281 Offset = Inst.getOperand(1);
1282 if (!Offset.isImm())
1283 break; // We'll deal with this situation later on when applying fixups.
1284 if (!isIntN(8, Offset.getImm()))
1285 return Error(IDLoc, "branch target out of range");
1286 if (OffsetToAlignment(Offset.getImm(), 2LL))
1287 return Error(IDLoc, "branch to misaligned address");
1292 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1293 // We still accept it but it is a normal nop.
1294 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1295 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1296 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1301 const unsigned Opcode = Inst.getOpcode();
1313 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1314 // The offset is handled above
1315 Opnd = Inst.getOperand(1);
1317 return Error(IDLoc, "expected immediate operand kind");
1318 Imm = Opnd.getImm();
1319 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1320 Opcode == Mips::BBIT1 ? 63 : 31))
1321 return Error(IDLoc, "immediate operand value out of range");
1323 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1325 Inst.getOperand(1).setImm(Imm - 32);
1333 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1335 Opnd = Inst.getOperand(3);
1337 return Error(IDLoc, "expected immediate operand kind");
1338 Imm = Opnd.getImm();
1339 if (Imm < 0 || Imm > 31)
1340 return Error(IDLoc, "immediate operand value out of range");
1342 Opnd = Inst.getOperand(2);
1344 return Error(IDLoc, "expected immediate operand kind");
1345 Imm = Opnd.getImm();
1346 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1347 Opcode == Mips::EXTS ? 63 : 31))
1348 return Error(IDLoc, "immediate operand value out of range");
1350 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1351 Inst.getOperand(2).setImm(Imm - 32);
1357 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1358 Opnd = Inst.getOperand(2);
1360 return Error(IDLoc, "expected immediate operand kind");
1361 Imm = Opnd.getImm();
1362 if (!isInt<10>(Imm))
1363 return Error(IDLoc, "immediate operand value out of range");
1368 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1369 // If this instruction has a delay slot and .set reorder is active,
1370 // emit a NOP after it.
1371 Instructions.push_back(Inst);
1373 if (hasShortDelaySlot(Inst.getOpcode())) {
1374 NopInst.setOpcode(Mips::MOVE16_MM);
1375 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1376 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1378 NopInst.setOpcode(Mips::SLL);
1379 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1380 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1381 NopInst.addOperand(MCOperand::CreateImm(0));
1383 Instructions.push_back(NopInst);
1387 if (MCID.mayLoad() || MCID.mayStore()) {
1388 // Check the offset of memory operand, if it is a symbol
1389 // reference or immediate we may have to expand instructions.
1390 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1391 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1392 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1393 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1394 MCOperand &Op = Inst.getOperand(i);
1396 int MemOffset = Op.getImm();
1397 if (MemOffset < -32768 || MemOffset > 32767) {
1398 // Offset can't exceed 16bit value.
1399 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1402 } else if (Op.isExpr()) {
1403 const MCExpr *Expr = Op.getExpr();
1404 if (Expr->getKind() == MCExpr::SymbolRef) {
1405 const MCSymbolRefExpr *SR =
1406 static_cast<const MCSymbolRefExpr *>(Expr);
1407 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1409 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1412 } else if (!isEvaluated(Expr)) {
1413 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1421 if (inMicroMipsMode()) {
1422 if (MCID.mayLoad()) {
1423 // Try to create 16-bit GP relative load instruction.
1424 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1425 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1426 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1427 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1428 MCOperand &Op = Inst.getOperand(i);
1430 int MemOffset = Op.getImm();
1431 MCOperand &DstReg = Inst.getOperand(0);
1432 MCOperand &BaseReg = Inst.getOperand(1);
1433 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1434 getContext().getRegisterInfo()->getRegClass(
1435 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1436 BaseReg.getReg() == Mips::GP) {
1438 TmpInst.setLoc(IDLoc);
1439 TmpInst.setOpcode(Mips::LWGP_MM);
1440 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1441 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1442 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1443 Instructions.push_back(TmpInst);
1451 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1456 switch (Inst.getOpcode()) {
1459 case Mips::ADDIUS5_MM:
1460 Opnd = Inst.getOperand(2);
1462 return Error(IDLoc, "expected immediate operand kind");
1463 Imm = Opnd.getImm();
1464 if (Imm < -8 || Imm > 7)
1465 return Error(IDLoc, "immediate operand value out of range");
1467 case Mips::ADDIUSP_MM:
1468 Opnd = Inst.getOperand(0);
1470 return Error(IDLoc, "expected immediate operand kind");
1471 Imm = Opnd.getImm();
1472 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1474 return Error(IDLoc, "immediate operand value out of range");
1476 case Mips::SLL16_MM:
1477 case Mips::SRL16_MM:
1478 Opnd = Inst.getOperand(2);
1480 return Error(IDLoc, "expected immediate operand kind");
1481 Imm = Opnd.getImm();
1482 if (Imm < 1 || Imm > 8)
1483 return Error(IDLoc, "immediate operand value out of range");
1486 Opnd = Inst.getOperand(1);
1488 return Error(IDLoc, "expected immediate operand kind");
1489 Imm = Opnd.getImm();
1490 if (Imm < -1 || Imm > 126)
1491 return Error(IDLoc, "immediate operand value out of range");
1493 case Mips::ADDIUR2_MM:
1494 Opnd = Inst.getOperand(2);
1496 return Error(IDLoc, "expected immediate operand kind");
1497 Imm = Opnd.getImm();
1498 if (!(Imm == 1 || Imm == -1 ||
1499 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1500 return Error(IDLoc, "immediate operand value out of range");
1502 case Mips::ADDIUR1SP_MM:
1503 Opnd = Inst.getOperand(1);
1505 return Error(IDLoc, "expected immediate operand kind");
1506 Imm = Opnd.getImm();
1507 if (OffsetToAlignment(Imm, 4LL))
1508 return Error(IDLoc, "misaligned immediate operand value");
1509 if (Imm < 0 || Imm > 255)
1510 return Error(IDLoc, "immediate operand value out of range");
1512 case Mips::ANDI16_MM:
1513 Opnd = Inst.getOperand(2);
1515 return Error(IDLoc, "expected immediate operand kind");
1516 Imm = Opnd.getImm();
1517 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1518 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1519 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1520 return Error(IDLoc, "immediate operand value out of range");
1522 case Mips::LBU16_MM:
1523 Opnd = Inst.getOperand(2);
1525 return Error(IDLoc, "expected immediate operand kind");
1526 Imm = Opnd.getImm();
1527 if (Imm < -1 || Imm > 14)
1528 return Error(IDLoc, "immediate operand value out of range");
1531 Opnd = Inst.getOperand(2);
1533 return Error(IDLoc, "expected immediate operand kind");
1534 Imm = Opnd.getImm();
1535 if (Imm < 0 || Imm > 15)
1536 return Error(IDLoc, "immediate operand value out of range");
1538 case Mips::LHU16_MM:
1540 Opnd = Inst.getOperand(2);
1542 return Error(IDLoc, "expected immediate operand kind");
1543 Imm = Opnd.getImm();
1544 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1545 return Error(IDLoc, "immediate operand value out of range");
1549 Opnd = Inst.getOperand(2);
1551 return Error(IDLoc, "expected immediate operand kind");
1552 Imm = Opnd.getImm();
1553 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1554 return Error(IDLoc, "immediate operand value out of range");
1558 Opnd = Inst.getOperand(2);
1560 return Error(IDLoc, "expected immediate operand kind");
1561 Imm = Opnd.getImm();
1562 if (!isUInt<5>(Imm))
1563 return Error(IDLoc, "immediate operand value out of range");
1565 case Mips::ADDIUPC_MM:
1566 MCOperand Opnd = Inst.getOperand(1);
1568 return Error(IDLoc, "expected immediate operand kind");
1569 int Imm = Opnd.getImm();
1570 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1571 return Error(IDLoc, "immediate operand value out of range");
1576 if (needsExpansion(Inst))
1577 return expandInstruction(Inst, IDLoc, Instructions);
1579 Instructions.push_back(Inst);
1584 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1586 switch (Inst.getOpcode()) {
1587 case Mips::LoadImm32Reg:
1588 case Mips::LoadAddr32Imm:
1589 case Mips::LoadAddr32Reg:
1590 case Mips::LoadImm64Reg:
1591 case Mips::B_MM_Pseudo:
1594 case Mips::JalOneReg:
1595 case Mips::JalTwoReg:
1602 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1603 SmallVectorImpl<MCInst> &Instructions) {
1604 switch (Inst.getOpcode()) {
1605 default: llvm_unreachable("unimplemented expansion");
1606 case Mips::LoadImm32Reg:
1607 return expandLoadImm(Inst, IDLoc, Instructions);
1608 case Mips::LoadImm64Reg:
1610 Error(IDLoc, "instruction requires a 64-bit architecture");
1613 return expandLoadImm(Inst, IDLoc, Instructions);
1614 case Mips::LoadAddr32Imm:
1615 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1616 case Mips::LoadAddr32Reg:
1617 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1618 case Mips::B_MM_Pseudo:
1619 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1622 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1623 case Mips::JalOneReg:
1624 case Mips::JalTwoReg:
1625 return expandJalWithRegs(Inst, IDLoc, Instructions);
1630 template <bool PerformShift>
1631 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1632 SmallVectorImpl<MCInst> &Instructions) {
1635 tmpInst.setOpcode(Mips::DSLL);
1636 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1637 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1638 tmpInst.addOperand(MCOperand::CreateImm(16));
1639 tmpInst.setLoc(IDLoc);
1640 Instructions.push_back(tmpInst);
1643 tmpInst.setOpcode(Mips::ORi);
1644 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1645 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1646 tmpInst.addOperand(Operand);
1647 tmpInst.setLoc(IDLoc);
1648 Instructions.push_back(tmpInst);
1651 template <int Shift, bool PerformShift>
1652 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1653 SmallVectorImpl<MCInst> &Instructions) {
1654 createShiftOr<PerformShift>(
1655 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1656 IDLoc, Instructions);
1660 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1661 SmallVectorImpl<MCInst> &Instructions) {
1662 // Create a JALR instruction which is going to replace the pseudo-JAL.
1664 JalrInst.setLoc(IDLoc);
1665 const MCOperand FirstRegOp = Inst.getOperand(0);
1666 const unsigned Opcode = Inst.getOpcode();
1668 if (Opcode == Mips::JalOneReg) {
1669 // jal $rs => jalr $rs
1670 if (inMicroMipsMode()) {
1671 JalrInst.setOpcode(Mips::JALR16_MM);
1672 JalrInst.addOperand(FirstRegOp);
1674 JalrInst.setOpcode(Mips::JALR);
1675 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1676 JalrInst.addOperand(FirstRegOp);
1678 } else if (Opcode == Mips::JalTwoReg) {
1679 // jal $rd, $rs => jalr $rd, $rs
1680 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1681 JalrInst.addOperand(FirstRegOp);
1682 const MCOperand SecondRegOp = Inst.getOperand(1);
1683 JalrInst.addOperand(SecondRegOp);
1685 Instructions.push_back(JalrInst);
1687 // If .set reorder is active, emit a NOP after it.
1688 if (AssemblerOptions.back()->isReorder()) {
1689 // This is a 32-bit NOP because these 2 pseudo-instructions
1690 // do not have a short delay slot.
1692 NopInst.setOpcode(Mips::SLL);
1693 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1694 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1695 NopInst.addOperand(MCOperand::CreateImm(0));
1696 Instructions.push_back(NopInst);
1702 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1703 SmallVectorImpl<MCInst> &Instructions) {
1705 const MCOperand &ImmOp = Inst.getOperand(1);
1706 assert(ImmOp.isImm() && "expected immediate operand kind");
1707 const MCOperand &RegOp = Inst.getOperand(0);
1708 assert(RegOp.isReg() && "expected register operand kind");
1710 int64_t ImmValue = ImmOp.getImm();
1711 tmpInst.setLoc(IDLoc);
1712 // FIXME: gas has a special case for values that are 000...1111, which
1713 // becomes a li -1 and then a dsrl
1714 if (0 <= ImmValue && ImmValue <= 65535) {
1715 // For 0 <= j <= 65535.
1716 // li d,j => ori d,$zero,j
1717 tmpInst.setOpcode(Mips::ORi);
1718 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1719 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1720 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1721 Instructions.push_back(tmpInst);
1722 } else if (ImmValue < 0 && ImmValue >= -32768) {
1723 // For -32768 <= j < 0.
1724 // li d,j => addiu d,$zero,j
1725 tmpInst.setOpcode(Mips::ADDiu);
1726 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1727 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1728 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1729 Instructions.push_back(tmpInst);
1730 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1731 // For any value of j that is representable as a 32-bit integer, create
1733 // li d,j => lui d,hi16(j)
1735 tmpInst.setOpcode(Mips::LUi);
1736 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1737 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1738 Instructions.push_back(tmpInst);
1739 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1740 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1742 Error(IDLoc, "instruction requires a 64-bit architecture");
1746 // <------- lo32 ------>
1747 // <------- hi32 ------>
1748 // <- hi16 -> <- lo16 ->
1749 // _________________________________
1751 // | 16-bytes | 16-bytes | 16-bytes |
1752 // |__________|__________|__________|
1754 // For any value of j that is representable as a 48-bit integer, create
1756 // li d,j => lui d,hi16(j)
1757 // ori d,d,hi16(lo32(j))
1759 // ori d,d,lo16(lo32(j))
1760 tmpInst.setOpcode(Mips::LUi);
1761 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1763 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1764 Instructions.push_back(tmpInst);
1765 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1766 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1769 Error(IDLoc, "instruction requires a 64-bit architecture");
1773 // <------- hi32 ------> <------- lo32 ------>
1774 // <- hi16 -> <- lo16 ->
1775 // ___________________________________________
1777 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1778 // |__________|__________|__________|__________|
1780 // For any value of j that isn't representable as a 48-bit integer.
1781 // li d,j => lui d,hi16(j)
1782 // ori d,d,lo16(hi32(j))
1784 // ori d,d,hi16(lo32(j))
1786 // ori d,d,lo16(lo32(j))
1787 tmpInst.setOpcode(Mips::LUi);
1788 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1790 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1791 Instructions.push_back(tmpInst);
1792 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1793 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1794 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1800 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1801 SmallVectorImpl<MCInst> &Instructions) {
1803 const MCOperand &ImmOp = Inst.getOperand(2);
1804 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1805 "expected immediate operand kind");
1806 if (!ImmOp.isImm()) {
1807 expandLoadAddressSym(Inst, IDLoc, Instructions);
1810 const MCOperand &SrcRegOp = Inst.getOperand(1);
1811 assert(SrcRegOp.isReg() && "expected register operand kind");
1812 const MCOperand &DstRegOp = Inst.getOperand(0);
1813 assert(DstRegOp.isReg() && "expected register operand kind");
1814 int ImmValue = ImmOp.getImm();
1815 if (-32768 <= ImmValue && ImmValue <= 65535) {
1816 // For -32768 <= j <= 65535.
1817 // la d,j(s) => addiu d,s,j
1818 tmpInst.setOpcode(Mips::ADDiu);
1819 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1820 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1821 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1822 Instructions.push_back(tmpInst);
1824 // For any other value of j that is representable as a 32-bit integer.
1825 // la d,j(s) => lui d,hi16(j)
1828 tmpInst.setOpcode(Mips::LUi);
1829 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1830 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1831 Instructions.push_back(tmpInst);
1833 tmpInst.setOpcode(Mips::ORi);
1834 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1835 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1836 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1837 Instructions.push_back(tmpInst);
1839 tmpInst.setOpcode(Mips::ADDu);
1840 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1841 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1842 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1843 Instructions.push_back(tmpInst);
1849 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1850 SmallVectorImpl<MCInst> &Instructions) {
1852 const MCOperand &ImmOp = Inst.getOperand(1);
1853 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1854 "expected immediate operand kind");
1855 if (!ImmOp.isImm()) {
1856 expandLoadAddressSym(Inst, IDLoc, Instructions);
1859 const MCOperand &RegOp = Inst.getOperand(0);
1860 assert(RegOp.isReg() && "expected register operand kind");
1861 int ImmValue = ImmOp.getImm();
1862 if (-32768 <= ImmValue && ImmValue <= 65535) {
1863 // For -32768 <= j <= 65535.
1864 // la d,j => addiu d,$zero,j
1865 tmpInst.setOpcode(Mips::ADDiu);
1866 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1867 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1868 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1869 Instructions.push_back(tmpInst);
1871 // For any other value of j that is representable as a 32-bit integer.
1872 // la d,j => lui d,hi16(j)
1874 tmpInst.setOpcode(Mips::LUi);
1875 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1876 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1877 Instructions.push_back(tmpInst);
1879 tmpInst.setOpcode(Mips::ORi);
1880 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1881 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1882 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1883 Instructions.push_back(tmpInst);
1889 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1890 SmallVectorImpl<MCInst> &Instructions) {
1891 // FIXME: If we do have a valid at register to use, we should generate a
1892 // slightly shorter sequence here.
1894 int ExprOperandNo = 1;
1895 // Sometimes the assembly parser will get the immediate expression as
1896 // a $zero + an immediate.
1897 if (Inst.getNumOperands() == 3) {
1898 assert(Inst.getOperand(1).getReg() ==
1899 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1902 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1903 assert(SymOp.isExpr() && "expected symbol operand kind");
1904 const MCOperand &RegOp = Inst.getOperand(0);
1905 unsigned RegNo = RegOp.getReg();
1906 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1907 const MCSymbolRefExpr *HiExpr =
1908 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1909 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1910 const MCSymbolRefExpr *LoExpr =
1911 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1912 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1914 // If it's a 64-bit architecture, expand to:
1915 // la d,sym => lui d,highest(sym)
1916 // ori d,d,higher(sym)
1918 // ori d,d,hi16(sym)
1920 // ori d,d,lo16(sym)
1921 const MCSymbolRefExpr *HighestExpr =
1922 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1923 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1924 const MCSymbolRefExpr *HigherExpr =
1925 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1926 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1928 tmpInst.setOpcode(Mips::LUi);
1929 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1930 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1931 Instructions.push_back(tmpInst);
1933 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1935 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1937 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1940 // Otherwise, expand to:
1941 // la d,sym => lui d,hi16(sym)
1942 // ori d,d,lo16(sym)
1943 tmpInst.setOpcode(Mips::LUi);
1944 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1945 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1946 Instructions.push_back(tmpInst);
1948 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1953 bool MipsAsmParser::expandUncondBranchMMPseudo(
1954 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1955 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1956 "unexpected number of operands");
1958 MCOperand Offset = Inst.getOperand(0);
1959 if (Offset.isExpr()) {
1961 Inst.setOpcode(Mips::BEQ_MM);
1962 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1963 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1964 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1966 assert(Offset.isImm() && "expected immediate operand kind");
1967 if (isIntN(11, Offset.getImm())) {
1968 // If offset fits into 11 bits then this instruction becomes microMIPS
1969 // 16-bit unconditional branch instruction.
1970 Inst.setOpcode(Mips::B16_MM);
1972 if (!isIntN(17, Offset.getImm()))
1973 Error(IDLoc, "branch target out of range");
1974 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1975 Error(IDLoc, "branch to misaligned address");
1977 Inst.setOpcode(Mips::BEQ_MM);
1978 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1979 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1980 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1983 Instructions.push_back(Inst);
1985 if (AssemblerOptions.back()->isReorder()) {
1986 // If .set reorder is active, emit a NOP after the branch instruction.
1988 NopInst.setOpcode(Mips::MOVE16_MM);
1989 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1990 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1991 Instructions.push_back(NopInst);
1996 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1997 SmallVectorImpl<MCInst> &Instructions,
1998 bool isLoad, bool isImmOpnd) {
1999 const MCSymbolRefExpr *SR;
2001 unsigned ImmOffset, HiOffset, LoOffset;
2002 const MCExpr *ExprOffset;
2004 // 1st operand is either the source or destination register.
2005 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2006 unsigned RegOpNum = Inst.getOperand(0).getReg();
2007 // 2nd operand is the base register.
2008 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2009 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2010 // 3rd operand is either an immediate or expression.
2012 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2013 ImmOffset = Inst.getOperand(2).getImm();
2014 LoOffset = ImmOffset & 0x0000ffff;
2015 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2016 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2017 if (LoOffset & 0x8000)
2020 ExprOffset = Inst.getOperand(2).getExpr();
2021 // All instructions will have the same location.
2022 TempInst.setLoc(IDLoc);
2023 // These are some of the types of expansions we perform here:
2024 // 1) lw $8, sym => lui $8, %hi(sym)
2025 // lw $8, %lo(sym)($8)
2026 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2028 // lw $8, %lo(offset)($9)
2029 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2031 // lw $8, %lo(offset)($at)
2032 // 4) sw $8, sym => lui $at, %hi(sym)
2033 // sw $8, %lo(sym)($at)
2034 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2036 // sw $8, %lo(offset)($at)
2037 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2038 // ldc1 $f0, %lo(sym)($at)
2040 // For load instructions we can use the destination register as a temporary
2041 // if base and dst are different (examples 1 and 2) and if the base register
2042 // is general purpose otherwise we must use $at (example 6) and error if it's
2043 // not available. For stores we must use $at (examples 4 and 5) because we
2044 // must not clobber the source register setting up the offset.
2045 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2046 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2047 unsigned RegClassIDOp0 =
2048 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2049 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2050 (RegClassIDOp0 == Mips::GPR64RegClassID);
2051 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2052 TmpRegNum = RegOpNum;
2054 int AT = getATReg(IDLoc);
2055 // At this point we need AT to perform the expansions and we exit if it is
2060 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
2063 TempInst.setOpcode(Mips::LUi);
2064 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2066 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2068 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2069 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2070 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2071 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2073 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2075 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2076 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2079 // Add the instruction to the list.
2080 Instructions.push_back(TempInst);
2081 // Prepare TempInst for next instruction.
2083 // Add temp register to base.
2084 TempInst.setOpcode(Mips::ADDu);
2085 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2086 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2087 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2088 Instructions.push_back(TempInst);
2090 // And finally, create original instruction with low part
2091 // of offset and new base.
2092 TempInst.setOpcode(Inst.getOpcode());
2093 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2094 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2096 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2098 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2099 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2100 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2102 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2104 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2105 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2108 Instructions.push_back(TempInst);
2113 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2114 SmallVectorImpl<MCInst> &Instructions) {
2115 unsigned OpNum = Inst.getNumOperands();
2116 unsigned Opcode = Inst.getOpcode();
2117 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2119 assert (Inst.getOperand(OpNum - 1).isImm() &&
2120 Inst.getOperand(OpNum - 2).isReg() &&
2121 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2123 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2124 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2125 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2126 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2127 // It can be implemented as SWM16 or LWM16 instruction.
2128 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2130 Inst.setOpcode(NewOpcode);
2131 Instructions.push_back(Inst);
2135 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2136 // As described by the Mips32r2 spec, the registers Rd and Rs for
2137 // jalr.hb must be different.
2138 unsigned Opcode = Inst.getOpcode();
2140 if (Opcode == Mips::JALR_HB &&
2141 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2142 return Match_RequiresDifferentSrcAndDst;
2144 return Match_Success;
2147 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2148 OperandVector &Operands,
2150 uint64_t &ErrorInfo,
2151 bool MatchingInlineAsm) {
2154 SmallVector<MCInst, 8> Instructions;
2155 unsigned MatchResult =
2156 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2158 switch (MatchResult) {
2159 case Match_Success: {
2160 if (processInstruction(Inst, IDLoc, Instructions))
2162 for (unsigned i = 0; i < Instructions.size(); i++)
2163 Out.EmitInstruction(Instructions[i], STI);
2166 case Match_MissingFeature:
2167 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2169 case Match_InvalidOperand: {
2170 SMLoc ErrorLoc = IDLoc;
2171 if (ErrorInfo != ~0ULL) {
2172 if (ErrorInfo >= Operands.size())
2173 return Error(IDLoc, "too few operands for instruction");
2175 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2176 if (ErrorLoc == SMLoc())
2180 return Error(ErrorLoc, "invalid operand for instruction");
2182 case Match_MnemonicFail:
2183 return Error(IDLoc, "invalid instruction");
2184 case Match_RequiresDifferentSrcAndDst:
2185 return Error(IDLoc, "source and destination must be different");
2188 llvm_unreachable("Implement any new match types added!");
2191 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
2192 if ((RegIndex != 0) &&
2193 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
2195 Warning(Loc, "used $at without \".set noat\"");
2197 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
2198 Twine(RegIndex) + "\"");
2203 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2204 SMRange Range, bool ShowColors) {
2205 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2206 Range, SMFixIt(Range, FixMsg),
2210 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2213 CC = StringSwitch<unsigned>(Name)
2249 if (!(isABI_N32() || isABI_N64()))
2252 if (12 <= CC && CC <= 15) {
2253 // Name is one of t4-t7
2254 AsmToken RegTok = getLexer().peekTok();
2255 SMRange RegRange = RegTok.getLocRange();
2257 StringRef FixedName = StringSwitch<StringRef>(Name)
2263 assert(FixedName != "" && "Register name is not one of t4-t7.");
2265 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2266 "Did you mean $" + FixedName + "?", RegRange);
2269 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2270 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2271 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2272 if (8 <= CC && CC <= 11)
2276 CC = StringSwitch<unsigned>(Name)
2288 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2291 CC = StringSwitch<unsigned>(Name)
2292 .Case("hwr_cpunum", 0)
2293 .Case("hwr_synci_step", 1)
2295 .Case("hwr_ccres", 3)
2296 .Case("hwr_ulr", 29)
2302 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2304 if (Name[0] == 'f') {
2305 StringRef NumString = Name.substr(1);
2307 if (NumString.getAsInteger(10, IntVal))
2308 return -1; // This is not an integer.
2309 if (IntVal > 31) // Maximum index for fpu register.
2316 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2318 if (Name.startswith("fcc")) {
2319 StringRef NumString = Name.substr(3);
2321 if (NumString.getAsInteger(10, IntVal))
2322 return -1; // This is not an integer.
2323 if (IntVal > 7) // There are only 8 fcc registers.
2330 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2332 if (Name.startswith("ac")) {
2333 StringRef NumString = Name.substr(2);
2335 if (NumString.getAsInteger(10, IntVal))
2336 return -1; // This is not an integer.
2337 if (IntVal > 3) // There are only 3 acc registers.
2344 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2347 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2356 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2359 CC = StringSwitch<unsigned>(Name)
2362 .Case("msaaccess", 2)
2364 .Case("msamodify", 4)
2365 .Case("msarequest", 5)
2367 .Case("msaunmap", 7)
2373 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2381 int MipsAsmParser::getATReg(SMLoc Loc) {
2382 int AT = AssemblerOptions.back()->getATRegNum();
2384 reportParseError(Loc,
2385 "pseudo-instruction requires $at, which is not available");
2389 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2390 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2393 unsigned MipsAsmParser::getGPR(int RegNo) {
2394 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2398 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2400 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2403 return getReg(RegClass, RegNum);
2406 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2407 MCAsmParser &Parser = getParser();
2408 DEBUG(dbgs() << "parseOperand\n");
2410 // Check if the current operand has a custom associated parser, if so, try to
2411 // custom parse the operand, or fallback to the general approach.
2412 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2413 if (ResTy == MatchOperand_Success)
2415 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2416 // there was a match, but an error occurred, in which case, just return that
2417 // the operand parsing failed.
2418 if (ResTy == MatchOperand_ParseFail)
2421 DEBUG(dbgs() << ".. Generic Parser\n");
2423 switch (getLexer().getKind()) {
2425 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2427 case AsmToken::Dollar: {
2428 // Parse the register.
2429 SMLoc S = Parser.getTok().getLoc();
2431 // Almost all registers have been parsed by custom parsers. There is only
2432 // one exception to this. $zero (and it's alias $0) will reach this point
2433 // for div, divu, and similar instructions because it is not an operand
2434 // to the instruction definition but an explicit register. Special case
2435 // this situation for now.
2436 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2439 // Maybe it is a symbol reference.
2440 StringRef Identifier;
2441 if (Parser.parseIdentifier(Identifier))
2444 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2445 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2446 // Otherwise create a symbol reference.
2448 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2450 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2453 // Else drop to expression parsing.
2454 case AsmToken::LParen:
2455 case AsmToken::Minus:
2456 case AsmToken::Plus:
2457 case AsmToken::Integer:
2458 case AsmToken::Tilde:
2459 case AsmToken::String: {
2460 DEBUG(dbgs() << ".. generic integer\n");
2461 OperandMatchResultTy ResTy = parseImm(Operands);
2462 return ResTy != MatchOperand_Success;
2464 case AsmToken::Percent: {
2465 // It is a symbol reference or constant expression.
2466 const MCExpr *IdVal;
2467 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2468 if (parseRelocOperand(IdVal))
2471 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2473 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2475 } // case AsmToken::Percent
2476 } // switch(getLexer().getKind())
2480 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2481 StringRef RelocStr) {
2483 // Check the type of the expression.
2484 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2485 // It's a constant, evaluate reloc value.
2487 switch (getVariantKind(RelocStr)) {
2488 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2489 // Get the 1st 16-bits.
2490 Val = MCE->getValue() & 0xffff;
2492 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2493 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2494 // 16 bits being negative.
2495 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2497 case MCSymbolRefExpr::VK_Mips_HIGHER:
2498 // Get the 3rd 16-bits.
2499 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2501 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2502 // Get the 4th 16-bits.
2503 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2506 report_fatal_error("unsupported reloc value");
2508 return MCConstantExpr::Create(Val, getContext());
2511 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2512 // It's a symbol, create a symbolic expression from the symbol.
2513 StringRef Symbol = MSRE->getSymbol().getName();
2514 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2515 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2519 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2520 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2522 // Try to create target expression.
2523 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2524 return MipsMCExpr::Create(VK, Expr, getContext());
2526 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2527 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2528 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2532 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2533 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2534 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2537 // Just return the original expression.
2541 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2543 switch (Expr->getKind()) {
2544 case MCExpr::Constant:
2546 case MCExpr::SymbolRef:
2547 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2548 case MCExpr::Binary:
2549 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2550 if (!isEvaluated(BE->getLHS()))
2552 return isEvaluated(BE->getRHS());
2555 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2556 case MCExpr::Target:
2562 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2563 MCAsmParser &Parser = getParser();
2564 Parser.Lex(); // Eat the % token.
2565 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2566 if (Tok.isNot(AsmToken::Identifier))
2569 std::string Str = Tok.getIdentifier().str();
2571 Parser.Lex(); // Eat the identifier.
2572 // Now make an expression from the rest of the operand.
2573 const MCExpr *IdVal;
2576 if (getLexer().getKind() == AsmToken::LParen) {
2578 Parser.Lex(); // Eat the '(' token.
2579 if (getLexer().getKind() == AsmToken::Percent) {
2580 Parser.Lex(); // Eat the % token.
2581 const AsmToken &nextTok = Parser.getTok();
2582 if (nextTok.isNot(AsmToken::Identifier))
2585 Str += nextTok.getIdentifier();
2586 Parser.Lex(); // Eat the identifier.
2587 if (getLexer().getKind() != AsmToken::LParen)
2592 if (getParser().parseParenExpression(IdVal, EndLoc))
2595 while (getLexer().getKind() == AsmToken::RParen)
2596 Parser.Lex(); // Eat the ')' token.
2599 return true; // Parenthesis must follow the relocation operand.
2601 Res = evaluateRelocExpr(IdVal, Str);
2605 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2607 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2608 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2609 if (ResTy == MatchOperand_Success) {
2610 assert(Operands.size() == 1);
2611 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2612 StartLoc = Operand.getStartLoc();
2613 EndLoc = Operand.getEndLoc();
2615 // AFAIK, we only support numeric registers and named GPR's in CFI
2617 // Don't worry about eating tokens before failing. Using an unrecognised
2618 // register is a parse error.
2619 if (Operand.isGPRAsmReg()) {
2620 // Resolve to GPR32 or GPR64 appropriately.
2621 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2624 return (RegNo == (unsigned)-1);
2627 assert(Operands.size() == 0);
2628 return (RegNo == (unsigned)-1);
2631 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2632 MCAsmParser &Parser = getParser();
2636 while (getLexer().getKind() == AsmToken::LParen)
2639 switch (getLexer().getKind()) {
2642 case AsmToken::Identifier:
2643 case AsmToken::LParen:
2644 case AsmToken::Integer:
2645 case AsmToken::Minus:
2646 case AsmToken::Plus:
2648 Result = getParser().parseParenExpression(Res, S);
2650 Result = (getParser().parseExpression(Res));
2651 while (getLexer().getKind() == AsmToken::RParen)
2654 case AsmToken::Percent:
2655 Result = parseRelocOperand(Res);
2660 MipsAsmParser::OperandMatchResultTy
2661 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2662 MCAsmParser &Parser = getParser();
2663 DEBUG(dbgs() << "parseMemOperand\n");
2664 const MCExpr *IdVal = nullptr;
2666 bool isParenExpr = false;
2667 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2668 // First operand is the offset.
2669 S = Parser.getTok().getLoc();
2671 if (getLexer().getKind() == AsmToken::LParen) {
2676 if (getLexer().getKind() != AsmToken::Dollar) {
2677 if (parseMemOffset(IdVal, isParenExpr))
2678 return MatchOperand_ParseFail;
2680 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2681 if (Tok.isNot(AsmToken::LParen)) {
2682 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2683 if (Mnemonic.getToken() == "la") {
2685 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2686 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2687 return MatchOperand_Success;
2689 if (Tok.is(AsmToken::EndOfStatement)) {
2691 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2693 // Zero register assumed, add a memory operand with ZERO as its base.
2694 // "Base" will be managed by k_Memory.
2695 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2698 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2699 return MatchOperand_Success;
2701 Error(Parser.getTok().getLoc(), "'(' expected");
2702 return MatchOperand_ParseFail;
2705 Parser.Lex(); // Eat the '(' token.
2708 Res = parseAnyRegister(Operands);
2709 if (Res != MatchOperand_Success)
2712 if (Parser.getTok().isNot(AsmToken::RParen)) {
2713 Error(Parser.getTok().getLoc(), "')' expected");
2714 return MatchOperand_ParseFail;
2717 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2719 Parser.Lex(); // Eat the ')' token.
2722 IdVal = MCConstantExpr::Create(0, getContext());
2724 // Replace the register operand with the memory operand.
2725 std::unique_ptr<MipsOperand> op(
2726 static_cast<MipsOperand *>(Operands.back().release()));
2727 // Remove the register from the operands.
2728 // "op" will be managed by k_Memory.
2729 Operands.pop_back();
2730 // Add the memory operand.
2731 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2733 if (IdVal->EvaluateAsAbsolute(Imm))
2734 IdVal = MCConstantExpr::Create(Imm, getContext());
2735 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2736 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2740 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2741 return MatchOperand_Success;
2744 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2745 MCAsmParser &Parser = getParser();
2746 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2748 SMLoc S = Parser.getTok().getLoc();
2750 if (Sym->isVariable())
2751 Expr = Sym->getVariableValue();
2754 if (Expr->getKind() == MCExpr::SymbolRef) {
2755 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2756 StringRef DefSymbol = Ref->getSymbol().getName();
2757 if (DefSymbol.startswith("$")) {
2758 OperandMatchResultTy ResTy =
2759 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2760 if (ResTy == MatchOperand_Success) {
2763 } else if (ResTy == MatchOperand_ParseFail)
2764 llvm_unreachable("Should never ParseFail");
2767 } else if (Expr->getKind() == MCExpr::Constant) {
2769 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2771 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2778 MipsAsmParser::OperandMatchResultTy
2779 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2780 StringRef Identifier,
2782 int Index = matchCPURegisterName(Identifier);
2784 Operands.push_back(MipsOperand::createGPRReg(
2785 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2786 return MatchOperand_Success;
2789 Index = matchHWRegsRegisterName(Identifier);
2791 Operands.push_back(MipsOperand::createHWRegsReg(
2792 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2793 return MatchOperand_Success;
2796 Index = matchFPURegisterName(Identifier);
2798 Operands.push_back(MipsOperand::createFGRReg(
2799 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2800 return MatchOperand_Success;
2803 Index = matchFCCRegisterName(Identifier);
2805 Operands.push_back(MipsOperand::createFCCReg(
2806 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2807 return MatchOperand_Success;
2810 Index = matchACRegisterName(Identifier);
2812 Operands.push_back(MipsOperand::createACCReg(
2813 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2814 return MatchOperand_Success;
2817 Index = matchMSA128RegisterName(Identifier);
2819 Operands.push_back(MipsOperand::createMSA128Reg(
2820 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2821 return MatchOperand_Success;
2824 Index = matchMSA128CtrlRegisterName(Identifier);
2826 Operands.push_back(MipsOperand::createMSACtrlReg(
2827 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2828 return MatchOperand_Success;
2831 return MatchOperand_NoMatch;
2834 MipsAsmParser::OperandMatchResultTy
2835 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2836 MCAsmParser &Parser = getParser();
2837 auto Token = Parser.getLexer().peekTok(false);
2839 if (Token.is(AsmToken::Identifier)) {
2840 DEBUG(dbgs() << ".. identifier\n");
2841 StringRef Identifier = Token.getIdentifier();
2842 OperandMatchResultTy ResTy =
2843 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2845 } else if (Token.is(AsmToken::Integer)) {
2846 DEBUG(dbgs() << ".. integer\n");
2847 Operands.push_back(MipsOperand::createNumericReg(
2848 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2850 return MatchOperand_Success;
2853 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2855 return MatchOperand_NoMatch;
2858 MipsAsmParser::OperandMatchResultTy
2859 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2860 MCAsmParser &Parser = getParser();
2861 DEBUG(dbgs() << "parseAnyRegister\n");
2863 auto Token = Parser.getTok();
2865 SMLoc S = Token.getLoc();
2867 if (Token.isNot(AsmToken::Dollar)) {
2868 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2869 if (Token.is(AsmToken::Identifier)) {
2870 if (searchSymbolAlias(Operands))
2871 return MatchOperand_Success;
2873 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2874 return MatchOperand_NoMatch;
2876 DEBUG(dbgs() << ".. $\n");
2878 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2879 if (ResTy == MatchOperand_Success) {
2881 Parser.Lex(); // identifier
2886 MipsAsmParser::OperandMatchResultTy
2887 MipsAsmParser::parseImm(OperandVector &Operands) {
2888 MCAsmParser &Parser = getParser();
2889 switch (getLexer().getKind()) {
2891 return MatchOperand_NoMatch;
2892 case AsmToken::LParen:
2893 case AsmToken::Minus:
2894 case AsmToken::Plus:
2895 case AsmToken::Integer:
2896 case AsmToken::Tilde:
2897 case AsmToken::String:
2901 const MCExpr *IdVal;
2902 SMLoc S = Parser.getTok().getLoc();
2903 if (getParser().parseExpression(IdVal))
2904 return MatchOperand_ParseFail;
2906 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2907 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2908 return MatchOperand_Success;
2911 MipsAsmParser::OperandMatchResultTy
2912 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2913 MCAsmParser &Parser = getParser();
2914 DEBUG(dbgs() << "parseJumpTarget\n");
2916 SMLoc S = getLexer().getLoc();
2918 // Integers and expressions are acceptable
2919 OperandMatchResultTy ResTy = parseImm(Operands);
2920 if (ResTy != MatchOperand_NoMatch)
2923 // Registers are a valid target and have priority over symbols.
2924 ResTy = parseAnyRegister(Operands);
2925 if (ResTy != MatchOperand_NoMatch)
2928 const MCExpr *Expr = nullptr;
2929 if (Parser.parseExpression(Expr)) {
2930 // We have no way of knowing if a symbol was consumed so we must ParseFail
2931 return MatchOperand_ParseFail;
2934 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2935 return MatchOperand_Success;
2938 MipsAsmParser::OperandMatchResultTy
2939 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2940 MCAsmParser &Parser = getParser();
2941 const MCExpr *IdVal;
2942 // If the first token is '$' we may have register operand.
2943 if (Parser.getTok().is(AsmToken::Dollar))
2944 return MatchOperand_NoMatch;
2945 SMLoc S = Parser.getTok().getLoc();
2946 if (getParser().parseExpression(IdVal))
2947 return MatchOperand_ParseFail;
2948 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2949 assert(MCE && "Unexpected MCExpr type.");
2950 int64_t Val = MCE->getValue();
2951 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2952 Operands.push_back(MipsOperand::CreateImm(
2953 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2954 return MatchOperand_Success;
2957 MipsAsmParser::OperandMatchResultTy
2958 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2959 MCAsmParser &Parser = getParser();
2960 switch (getLexer().getKind()) {
2962 return MatchOperand_NoMatch;
2963 case AsmToken::LParen:
2964 case AsmToken::Plus:
2965 case AsmToken::Minus:
2966 case AsmToken::Integer:
2971 SMLoc S = Parser.getTok().getLoc();
2973 if (getParser().parseExpression(Expr))
2974 return MatchOperand_ParseFail;
2977 if (!Expr->EvaluateAsAbsolute(Val)) {
2978 Error(S, "expected immediate value");
2979 return MatchOperand_ParseFail;
2982 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2983 // and because the CPU always adds one to the immediate field, the allowed
2984 // range becomes 1..4. We'll only check the range here and will deal
2985 // with the addition/subtraction when actually decoding/encoding
2987 if (Val < 1 || Val > 4) {
2988 Error(S, "immediate not in range (1..4)");
2989 return MatchOperand_ParseFail;
2993 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2994 return MatchOperand_Success;
2997 MipsAsmParser::OperandMatchResultTy
2998 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2999 MCAsmParser &Parser = getParser();
3000 SmallVector<unsigned, 10> Regs;
3002 unsigned PrevReg = Mips::NoRegister;
3003 bool RegRange = false;
3004 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3006 if (Parser.getTok().isNot(AsmToken::Dollar))
3007 return MatchOperand_ParseFail;
3009 SMLoc S = Parser.getTok().getLoc();
3010 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3011 SMLoc E = getLexer().getLoc();
3012 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3013 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3015 // Remove last register operand because registers from register range
3016 // should be inserted first.
3017 if (RegNo == Mips::RA) {
3018 Regs.push_back(RegNo);
3020 unsigned TmpReg = PrevReg + 1;
3021 while (TmpReg <= RegNo) {
3022 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3023 Error(E, "invalid register operand");
3024 return MatchOperand_ParseFail;
3028 Regs.push_back(TmpReg++);
3034 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3035 (RegNo != Mips::RA)) {
3036 Error(E, "$16 or $31 expected");
3037 return MatchOperand_ParseFail;
3038 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3039 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3040 Error(E, "invalid register operand");
3041 return MatchOperand_ParseFail;
3042 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3043 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3044 Error(E, "consecutive register numbers expected");
3045 return MatchOperand_ParseFail;
3048 Regs.push_back(RegNo);
3051 if (Parser.getTok().is(AsmToken::Minus))
3054 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3055 !Parser.getTok().isNot(AsmToken::Comma)) {
3056 Error(E, "',' or '-' expected");
3057 return MatchOperand_ParseFail;
3060 Lex(); // Consume comma or minus
3061 if (Parser.getTok().isNot(AsmToken::Dollar))
3067 SMLoc E = Parser.getTok().getLoc();
3068 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3069 parseMemOperand(Operands);
3070 return MatchOperand_Success;
3073 MipsAsmParser::OperandMatchResultTy
3074 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3075 MCAsmParser &Parser = getParser();
3077 SMLoc S = Parser.getTok().getLoc();
3078 if (parseAnyRegister(Operands) != MatchOperand_Success)
3079 return MatchOperand_ParseFail;
3081 SMLoc E = Parser.getTok().getLoc();
3082 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3083 unsigned Reg = Op.getGPR32Reg();
3084 Operands.pop_back();
3085 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3086 return MatchOperand_Success;
3089 MipsAsmParser::OperandMatchResultTy
3090 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3091 MCAsmParser &Parser = getParser();
3092 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3093 SmallVector<unsigned, 10> Regs;
3095 if (Parser.getTok().isNot(AsmToken::Dollar))
3096 return MatchOperand_ParseFail;
3098 SMLoc S = Parser.getTok().getLoc();
3100 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3101 return MatchOperand_ParseFail;
3103 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3104 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3105 Regs.push_back(RegNo);
3107 SMLoc E = Parser.getTok().getLoc();
3108 if (Parser.getTok().isNot(AsmToken::Comma)) {
3109 Error(E, "',' expected");
3110 return MatchOperand_ParseFail;
3116 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3117 return MatchOperand_ParseFail;
3119 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3120 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3121 Regs.push_back(RegNo);
3123 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3125 return MatchOperand_Success;
3128 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3130 MCSymbolRefExpr::VariantKind VK =
3131 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3132 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3133 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3134 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3135 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3136 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3137 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3138 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3139 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3140 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3141 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3142 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3143 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3144 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3145 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3146 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3147 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3148 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3149 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3150 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3151 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3152 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3153 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3154 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3155 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3156 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3157 .Default(MCSymbolRefExpr::VK_None);
3159 assert(VK != MCSymbolRefExpr::VK_None);
3164 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3166 /// ::= '(', register, ')'
3167 /// handle it before we iterate so we don't get tripped up by the lack of
3169 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3170 MCAsmParser &Parser = getParser();
3171 if (getLexer().is(AsmToken::LParen)) {
3173 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3175 if (parseOperand(Operands, Name)) {
3176 SMLoc Loc = getLexer().getLoc();
3177 Parser.eatToEndOfStatement();
3178 return Error(Loc, "unexpected token in argument list");
3180 if (Parser.getTok().isNot(AsmToken::RParen)) {
3181 SMLoc Loc = getLexer().getLoc();
3182 Parser.eatToEndOfStatement();
3183 return Error(Loc, "unexpected token, expected ')'");
3186 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3192 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3193 /// either one of these.
3194 /// ::= '[', register, ']'
3195 /// ::= '[', integer, ']'
3196 /// handle it before we iterate so we don't get tripped up by the lack of
3198 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3199 OperandVector &Operands) {
3200 MCAsmParser &Parser = getParser();
3201 if (getLexer().is(AsmToken::LBrac)) {
3203 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3205 if (parseOperand(Operands, Name)) {
3206 SMLoc Loc = getLexer().getLoc();
3207 Parser.eatToEndOfStatement();
3208 return Error(Loc, "unexpected token in argument list");
3210 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3211 SMLoc Loc = getLexer().getLoc();
3212 Parser.eatToEndOfStatement();
3213 return Error(Loc, "unexpected token, expected ']'");
3216 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3222 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3223 SMLoc NameLoc, OperandVector &Operands) {
3224 MCAsmParser &Parser = getParser();
3225 DEBUG(dbgs() << "ParseInstruction\n");
3227 // We have reached first instruction, module directive are now forbidden.
3228 getTargetStreamer().forbidModuleDirective();
3230 // Check if we have valid mnemonic
3231 if (!mnemonicIsValid(Name, 0)) {
3232 Parser.eatToEndOfStatement();
3233 return Error(NameLoc, "unknown instruction");
3235 // First operand in MCInst is instruction mnemonic.
3236 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3238 // Read the remaining operands.
3239 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3240 // Read the first operand.
3241 if (parseOperand(Operands, Name)) {
3242 SMLoc Loc = getLexer().getLoc();
3243 Parser.eatToEndOfStatement();
3244 return Error(Loc, "unexpected token in argument list");
3246 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3248 // AFAIK, parenthesis suffixes are never on the first operand
3250 while (getLexer().is(AsmToken::Comma)) {
3251 Parser.Lex(); // Eat the comma.
3252 // Parse and remember the operand.
3253 if (parseOperand(Operands, Name)) {
3254 SMLoc Loc = getLexer().getLoc();
3255 Parser.eatToEndOfStatement();
3256 return Error(Loc, "unexpected token in argument list");
3258 // Parse bracket and parenthesis suffixes before we iterate
3259 if (getLexer().is(AsmToken::LBrac)) {
3260 if (parseBracketSuffix(Name, Operands))
3262 } else if (getLexer().is(AsmToken::LParen) &&
3263 parseParenSuffix(Name, Operands))
3267 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3268 SMLoc Loc = getLexer().getLoc();
3269 Parser.eatToEndOfStatement();
3270 return Error(Loc, "unexpected token in argument list");
3272 Parser.Lex(); // Consume the EndOfStatement.
3276 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3277 MCAsmParser &Parser = getParser();
3278 SMLoc Loc = getLexer().getLoc();
3279 Parser.eatToEndOfStatement();
3280 return Error(Loc, ErrorMsg);
3283 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3284 return Error(Loc, ErrorMsg);
3287 bool MipsAsmParser::parseSetNoAtDirective() {
3288 MCAsmParser &Parser = getParser();
3289 // Line should look like: ".set noat".
3291 // Set the $at register to $0.
3292 AssemblerOptions.back()->setATReg(0);
3294 Parser.Lex(); // Eat "noat".
3296 // If this is not the end of the statement, report an error.
3297 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3298 reportParseError("unexpected token, expected end of statement");
3302 getTargetStreamer().emitDirectiveSetNoAt();
3303 Parser.Lex(); // Consume the EndOfStatement.
3307 bool MipsAsmParser::parseSetAtDirective() {
3308 // Line can be: ".set at", which sets $at to $1
3309 // or ".set at=$reg", which sets $at to $reg.
3310 MCAsmParser &Parser = getParser();
3311 Parser.Lex(); // Eat "at".
3313 if (getLexer().is(AsmToken::EndOfStatement)) {
3314 // No register was specified, so we set $at to $1.
3315 AssemblerOptions.back()->setATReg(1);
3317 getTargetStreamer().emitDirectiveSetAt();
3318 Parser.Lex(); // Consume the EndOfStatement.
3322 if (getLexer().isNot(AsmToken::Equal)) {
3323 reportParseError("unexpected token, expected equals sign");
3326 Parser.Lex(); // Eat "=".
3328 if (getLexer().isNot(AsmToken::Dollar)) {
3329 if (getLexer().is(AsmToken::EndOfStatement)) {
3330 reportParseError("no register specified");
3333 reportParseError("unexpected token, expected dollar sign '$'");
3337 Parser.Lex(); // Eat "$".
3339 // Find out what "reg" is.
3341 const AsmToken &Reg = Parser.getTok();
3342 if (Reg.is(AsmToken::Identifier)) {
3343 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3344 } else if (Reg.is(AsmToken::Integer)) {
3345 AtRegNo = Reg.getIntVal();
3347 reportParseError("unexpected token, expected identifier or integer");
3351 // Check if $reg is a valid register. If it is, set $at to $reg.
3352 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3353 reportParseError("invalid register");
3356 Parser.Lex(); // Eat "reg".
3358 // If this is not the end of the statement, report an error.
3359 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3360 reportParseError("unexpected token, expected end of statement");
3364 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3366 Parser.Lex(); // Consume the EndOfStatement.
3370 bool MipsAsmParser::parseSetReorderDirective() {
3371 MCAsmParser &Parser = getParser();
3373 // If this is not the end of the statement, report an error.
3374 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3375 reportParseError("unexpected token, expected end of statement");
3378 AssemblerOptions.back()->setReorder();
3379 getTargetStreamer().emitDirectiveSetReorder();
3380 Parser.Lex(); // Consume the EndOfStatement.
3384 bool MipsAsmParser::parseSetNoReorderDirective() {
3385 MCAsmParser &Parser = getParser();
3387 // If this is not the end of the statement, report an error.
3388 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3389 reportParseError("unexpected token, expected end of statement");
3392 AssemblerOptions.back()->setNoReorder();
3393 getTargetStreamer().emitDirectiveSetNoReorder();
3394 Parser.Lex(); // Consume the EndOfStatement.
3398 bool MipsAsmParser::parseSetMacroDirective() {
3399 MCAsmParser &Parser = getParser();
3401 // If this is not the end of the statement, report an error.
3402 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3403 reportParseError("unexpected token, expected end of statement");
3406 AssemblerOptions.back()->setMacro();
3407 Parser.Lex(); // Consume the EndOfStatement.
3411 bool MipsAsmParser::parseSetNoMacroDirective() {
3412 MCAsmParser &Parser = getParser();
3414 // If this is not the end of the statement, report an error.
3415 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3416 reportParseError("unexpected token, expected end of statement");
3419 if (AssemblerOptions.back()->isReorder()) {
3420 reportParseError("`noreorder' must be set before `nomacro'");
3423 AssemblerOptions.back()->setNoMacro();
3424 Parser.Lex(); // Consume the EndOfStatement.
3428 bool MipsAsmParser::parseSetMsaDirective() {
3429 MCAsmParser &Parser = getParser();
3432 // If this is not the end of the statement, report an error.
3433 if (getLexer().isNot(AsmToken::EndOfStatement))
3434 return reportParseError("unexpected token, expected end of statement");
3436 setFeatureBits(Mips::FeatureMSA, "msa");
3437 getTargetStreamer().emitDirectiveSetMsa();
3441 bool MipsAsmParser::parseSetNoMsaDirective() {
3442 MCAsmParser &Parser = getParser();
3445 // If this is not the end of the statement, report an error.
3446 if (getLexer().isNot(AsmToken::EndOfStatement))
3447 return reportParseError("unexpected token, expected end of statement");
3449 clearFeatureBits(Mips::FeatureMSA, "msa");
3450 getTargetStreamer().emitDirectiveSetNoMsa();
3454 bool MipsAsmParser::parseSetNoDspDirective() {
3455 MCAsmParser &Parser = getParser();
3456 Parser.Lex(); // Eat "nodsp".
3458 // If this is not the end of the statement, report an error.
3459 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3460 reportParseError("unexpected token, expected end of statement");
3464 clearFeatureBits(Mips::FeatureDSP, "dsp");
3465 getTargetStreamer().emitDirectiveSetNoDsp();
3469 bool MipsAsmParser::parseSetMips16Directive() {
3470 MCAsmParser &Parser = getParser();
3471 Parser.Lex(); // Eat "mips16".
3473 // If this is not the end of the statement, report an error.
3474 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3475 reportParseError("unexpected token, expected end of statement");
3479 setFeatureBits(Mips::FeatureMips16, "mips16");
3480 getTargetStreamer().emitDirectiveSetMips16();
3481 Parser.Lex(); // Consume the EndOfStatement.
3485 bool MipsAsmParser::parseSetNoMips16Directive() {
3486 MCAsmParser &Parser = getParser();
3487 Parser.Lex(); // Eat "nomips16".
3489 // If this is not the end of the statement, report an error.
3490 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3491 reportParseError("unexpected token, expected end of statement");
3495 clearFeatureBits(Mips::FeatureMips16, "mips16");
3496 getTargetStreamer().emitDirectiveSetNoMips16();
3497 Parser.Lex(); // Consume the EndOfStatement.
3501 bool MipsAsmParser::parseSetFpDirective() {
3502 MCAsmParser &Parser = getParser();
3503 MipsABIFlagsSection::FpABIKind FpAbiVal;
3504 // Line can be: .set fp=32
3507 Parser.Lex(); // Eat fp token
3508 AsmToken Tok = Parser.getTok();
3509 if (Tok.isNot(AsmToken::Equal)) {
3510 reportParseError("unexpected token, expected equals sign '='");
3513 Parser.Lex(); // Eat '=' token.
3514 Tok = Parser.getTok();
3516 if (!parseFpABIValue(FpAbiVal, ".set"))
3519 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3520 reportParseError("unexpected token, expected end of statement");
3523 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3524 Parser.Lex(); // Consume the EndOfStatement.
3528 bool MipsAsmParser::parseSetPopDirective() {
3529 MCAsmParser &Parser = getParser();
3530 SMLoc Loc = getLexer().getLoc();
3533 if (getLexer().isNot(AsmToken::EndOfStatement))
3534 return reportParseError("unexpected token, expected end of statement");
3536 // Always keep an element on the options "stack" to prevent the user
3537 // from changing the initial options. This is how we remember them.
3538 if (AssemblerOptions.size() == 2)
3539 return reportParseError(Loc, ".set pop with no .set push");
3541 AssemblerOptions.pop_back();
3542 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3544 getTargetStreamer().emitDirectiveSetPop();
3548 bool MipsAsmParser::parseSetPushDirective() {
3549 MCAsmParser &Parser = getParser();
3551 if (getLexer().isNot(AsmToken::EndOfStatement))
3552 return reportParseError("unexpected token, expected end of statement");
3554 // Create a copy of the current assembler options environment and push it.
3555 AssemblerOptions.push_back(
3556 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3558 getTargetStreamer().emitDirectiveSetPush();
3562 bool MipsAsmParser::parseSetAssignment() {
3564 const MCExpr *Value;
3565 MCAsmParser &Parser = getParser();
3567 if (Parser.parseIdentifier(Name))
3568 reportParseError("expected identifier after .set");
3570 if (getLexer().isNot(AsmToken::Comma))
3571 return reportParseError("unexpected token, expected comma");
3574 if (Parser.parseExpression(Value))
3575 return reportParseError("expected valid expression after comma");
3577 // Check if the Name already exists as a symbol.
3578 MCSymbol *Sym = getContext().LookupSymbol(Name);
3580 return reportParseError("symbol already defined");
3581 Sym = getContext().GetOrCreateSymbol(Name);
3582 Sym->setVariableValue(Value);
3587 bool MipsAsmParser::parseSetMips0Directive() {
3588 MCAsmParser &Parser = getParser();
3590 if (getLexer().isNot(AsmToken::EndOfStatement))
3591 return reportParseError("unexpected token, expected end of statement");
3593 // Reset assembler options to their initial values.
3594 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3595 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3597 getTargetStreamer().emitDirectiveSetMips0();
3601 bool MipsAsmParser::parseSetArchDirective() {
3602 MCAsmParser &Parser = getParser();
3604 if (getLexer().isNot(AsmToken::Equal))
3605 return reportParseError("unexpected token, expected equals sign");
3609 if (Parser.parseIdentifier(Arch))
3610 return reportParseError("expected arch identifier");
3612 StringRef ArchFeatureName =
3613 StringSwitch<StringRef>(Arch)
3614 .Case("mips1", "mips1")
3615 .Case("mips2", "mips2")
3616 .Case("mips3", "mips3")
3617 .Case("mips4", "mips4")
3618 .Case("mips5", "mips5")
3619 .Case("mips32", "mips32")
3620 .Case("mips32r2", "mips32r2")
3621 .Case("mips32r3", "mips32r3")
3622 .Case("mips32r5", "mips32r5")
3623 .Case("mips32r6", "mips32r6")
3624 .Case("mips64", "mips64")
3625 .Case("mips64r2", "mips64r2")
3626 .Case("mips64r3", "mips64r3")
3627 .Case("mips64r5", "mips64r5")
3628 .Case("mips64r6", "mips64r6")
3629 .Case("cnmips", "cnmips")
3630 .Case("r4000", "mips3") // This is an implementation of Mips3.
3633 if (ArchFeatureName.empty())
3634 return reportParseError("unsupported architecture");
3636 selectArch(ArchFeatureName);
3637 getTargetStreamer().emitDirectiveSetArch(Arch);
3641 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3642 MCAsmParser &Parser = getParser();
3644 if (getLexer().isNot(AsmToken::EndOfStatement))
3645 return reportParseError("unexpected token, expected end of statement");
3649 llvm_unreachable("Unimplemented feature");
3650 case Mips::FeatureDSP:
3651 setFeatureBits(Mips::FeatureDSP, "dsp");
3652 getTargetStreamer().emitDirectiveSetDsp();
3654 case Mips::FeatureMicroMips:
3655 getTargetStreamer().emitDirectiveSetMicroMips();
3657 case Mips::FeatureMips1:
3658 selectArch("mips1");
3659 getTargetStreamer().emitDirectiveSetMips1();
3661 case Mips::FeatureMips2:
3662 selectArch("mips2");
3663 getTargetStreamer().emitDirectiveSetMips2();
3665 case Mips::FeatureMips3:
3666 selectArch("mips3");
3667 getTargetStreamer().emitDirectiveSetMips3();
3669 case Mips::FeatureMips4:
3670 selectArch("mips4");
3671 getTargetStreamer().emitDirectiveSetMips4();
3673 case Mips::FeatureMips5:
3674 selectArch("mips5");
3675 getTargetStreamer().emitDirectiveSetMips5();
3677 case Mips::FeatureMips32:
3678 selectArch("mips32");
3679 getTargetStreamer().emitDirectiveSetMips32();
3681 case Mips::FeatureMips32r2:
3682 selectArch("mips32r2");
3683 getTargetStreamer().emitDirectiveSetMips32R2();
3685 case Mips::FeatureMips32r3:
3686 selectArch("mips32r3");
3687 getTargetStreamer().emitDirectiveSetMips32R3();
3689 case Mips::FeatureMips32r5:
3690 selectArch("mips32r5");
3691 getTargetStreamer().emitDirectiveSetMips32R5();
3693 case Mips::FeatureMips32r6:
3694 selectArch("mips32r6");
3695 getTargetStreamer().emitDirectiveSetMips32R6();
3697 case Mips::FeatureMips64:
3698 selectArch("mips64");
3699 getTargetStreamer().emitDirectiveSetMips64();
3701 case Mips::FeatureMips64r2:
3702 selectArch("mips64r2");
3703 getTargetStreamer().emitDirectiveSetMips64R2();
3705 case Mips::FeatureMips64r3:
3706 selectArch("mips64r3");
3707 getTargetStreamer().emitDirectiveSetMips64R3();
3709 case Mips::FeatureMips64r5:
3710 selectArch("mips64r5");
3711 getTargetStreamer().emitDirectiveSetMips64R5();
3713 case Mips::FeatureMips64r6:
3714 selectArch("mips64r6");
3715 getTargetStreamer().emitDirectiveSetMips64R6();
3721 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3722 MCAsmParser &Parser = getParser();
3723 if (getLexer().isNot(AsmToken::Comma)) {
3724 SMLoc Loc = getLexer().getLoc();
3725 Parser.eatToEndOfStatement();
3726 return Error(Loc, ErrorStr);
3729 Parser.Lex(); // Eat the comma.
3733 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3734 if (AssemblerOptions.back()->isReorder())
3735 Warning(Loc, ".cpload should be inside a noreorder section");
3737 if (inMips16Mode()) {
3738 reportParseError(".cpload is not supported in Mips16 mode");
3742 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3743 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3744 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3745 reportParseError("expected register containing function address");
3749 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3750 if (!RegOpnd.isGPRAsmReg()) {
3751 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3755 // If this is not the end of the statement, report an error.
3756 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3757 reportParseError("unexpected token, expected end of statement");
3761 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3765 bool MipsAsmParser::parseDirectiveCPSetup() {
3766 MCAsmParser &Parser = getParser();
3769 bool SaveIsReg = true;
3771 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3772 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3773 if (ResTy == MatchOperand_NoMatch) {
3774 reportParseError("expected register containing function address");
3775 Parser.eatToEndOfStatement();
3779 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3780 if (!FuncRegOpnd.isGPRAsmReg()) {
3781 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3782 Parser.eatToEndOfStatement();
3786 FuncReg = FuncRegOpnd.getGPR32Reg();
3789 if (!eatComma("unexpected token, expected comma"))
3792 ResTy = parseAnyRegister(TmpReg);
3793 if (ResTy == MatchOperand_NoMatch) {
3794 const AsmToken &Tok = Parser.getTok();
3795 if (Tok.is(AsmToken::Integer)) {
3796 Save = Tok.getIntVal();
3800 reportParseError("expected save register or stack offset");
3801 Parser.eatToEndOfStatement();
3805 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3806 if (!SaveOpnd.isGPRAsmReg()) {
3807 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3808 Parser.eatToEndOfStatement();
3811 Save = SaveOpnd.getGPR32Reg();
3814 if (!eatComma("unexpected token, expected comma"))
3818 if (Parser.parseExpression(Expr)) {
3819 reportParseError("expected expression");
3823 if (Expr->getKind() != MCExpr::SymbolRef) {
3824 reportParseError("expected symbol");
3827 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3829 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3834 bool MipsAsmParser::parseDirectiveNaN() {
3835 MCAsmParser &Parser = getParser();
3836 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3837 const AsmToken &Tok = Parser.getTok();
3839 if (Tok.getString() == "2008") {
3841 getTargetStreamer().emitDirectiveNaN2008();
3843 } else if (Tok.getString() == "legacy") {
3845 getTargetStreamer().emitDirectiveNaNLegacy();
3849 // If we don't recognize the option passed to the .nan
3850 // directive (e.g. no option or unknown option), emit an error.
3851 reportParseError("invalid option in .nan directive");
3855 bool MipsAsmParser::parseDirectiveSet() {
3856 MCAsmParser &Parser = getParser();
3857 // Get the next token.
3858 const AsmToken &Tok = Parser.getTok();
3860 if (Tok.getString() == "noat") {
3861 return parseSetNoAtDirective();
3862 } else if (Tok.getString() == "at") {
3863 return parseSetAtDirective();
3864 } else if (Tok.getString() == "arch") {
3865 return parseSetArchDirective();
3866 } else if (Tok.getString() == "fp") {
3867 return parseSetFpDirective();
3868 } else if (Tok.getString() == "pop") {
3869 return parseSetPopDirective();
3870 } else if (Tok.getString() == "push") {
3871 return parseSetPushDirective();
3872 } else if (Tok.getString() == "reorder") {
3873 return parseSetReorderDirective();
3874 } else if (Tok.getString() == "noreorder") {
3875 return parseSetNoReorderDirective();
3876 } else if (Tok.getString() == "macro") {
3877 return parseSetMacroDirective();
3878 } else if (Tok.getString() == "nomacro") {
3879 return parseSetNoMacroDirective();
3880 } else if (Tok.getString() == "mips16") {
3881 return parseSetMips16Directive();
3882 } else if (Tok.getString() == "nomips16") {
3883 return parseSetNoMips16Directive();
3884 } else if (Tok.getString() == "nomicromips") {
3885 getTargetStreamer().emitDirectiveSetNoMicroMips();
3886 Parser.eatToEndOfStatement();
3888 } else if (Tok.getString() == "micromips") {
3889 return parseSetFeature(Mips::FeatureMicroMips);
3890 } else if (Tok.getString() == "mips0") {
3891 return parseSetMips0Directive();
3892 } else if (Tok.getString() == "mips1") {
3893 return parseSetFeature(Mips::FeatureMips1);
3894 } else if (Tok.getString() == "mips2") {
3895 return parseSetFeature(Mips::FeatureMips2);
3896 } else if (Tok.getString() == "mips3") {
3897 return parseSetFeature(Mips::FeatureMips3);
3898 } else if (Tok.getString() == "mips4") {
3899 return parseSetFeature(Mips::FeatureMips4);
3900 } else if (Tok.getString() == "mips5") {
3901 return parseSetFeature(Mips::FeatureMips5);
3902 } else if (Tok.getString() == "mips32") {
3903 return parseSetFeature(Mips::FeatureMips32);
3904 } else if (Tok.getString() == "mips32r2") {
3905 return parseSetFeature(Mips::FeatureMips32r2);
3906 } else if (Tok.getString() == "mips32r3") {
3907 return parseSetFeature(Mips::FeatureMips32r3);
3908 } else if (Tok.getString() == "mips32r5") {
3909 return parseSetFeature(Mips::FeatureMips32r5);
3910 } else if (Tok.getString() == "mips32r6") {
3911 return parseSetFeature(Mips::FeatureMips32r6);
3912 } else if (Tok.getString() == "mips64") {
3913 return parseSetFeature(Mips::FeatureMips64);
3914 } else if (Tok.getString() == "mips64r2") {
3915 return parseSetFeature(Mips::FeatureMips64r2);
3916 } else if (Tok.getString() == "mips64r3") {
3917 return parseSetFeature(Mips::FeatureMips64r3);
3918 } else if (Tok.getString() == "mips64r5") {
3919 return parseSetFeature(Mips::FeatureMips64r5);
3920 } else if (Tok.getString() == "mips64r6") {
3921 return parseSetFeature(Mips::FeatureMips64r6);
3922 } else if (Tok.getString() == "dsp") {
3923 return parseSetFeature(Mips::FeatureDSP);
3924 } else if (Tok.getString() == "nodsp") {
3925 return parseSetNoDspDirective();
3926 } else if (Tok.getString() == "msa") {
3927 return parseSetMsaDirective();
3928 } else if (Tok.getString() == "nomsa") {
3929 return parseSetNoMsaDirective();
3931 // It is just an identifier, look for an assignment.
3932 parseSetAssignment();
3939 /// parseDataDirective
3940 /// ::= .word [ expression (, expression)* ]
3941 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3942 MCAsmParser &Parser = getParser();
3943 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3945 const MCExpr *Value;
3946 if (getParser().parseExpression(Value))
3949 getParser().getStreamer().EmitValue(Value, Size);
3951 if (getLexer().is(AsmToken::EndOfStatement))
3954 if (getLexer().isNot(AsmToken::Comma))
3955 return Error(L, "unexpected token, expected comma");
3964 /// parseDirectiveGpWord
3965 /// ::= .gpword local_sym
3966 bool MipsAsmParser::parseDirectiveGpWord() {
3967 MCAsmParser &Parser = getParser();
3968 const MCExpr *Value;
3969 // EmitGPRel32Value requires an expression, so we are using base class
3970 // method to evaluate the expression.
3971 if (getParser().parseExpression(Value))
3973 getParser().getStreamer().EmitGPRel32Value(Value);
3975 if (getLexer().isNot(AsmToken::EndOfStatement))
3976 return Error(getLexer().getLoc(),
3977 "unexpected token, expected end of statement");
3978 Parser.Lex(); // Eat EndOfStatement token.
3982 /// parseDirectiveGpDWord
3983 /// ::= .gpdword local_sym
3984 bool MipsAsmParser::parseDirectiveGpDWord() {
3985 MCAsmParser &Parser = getParser();
3986 const MCExpr *Value;
3987 // EmitGPRel64Value requires an expression, so we are using base class
3988 // method to evaluate the expression.
3989 if (getParser().parseExpression(Value))
3991 getParser().getStreamer().EmitGPRel64Value(Value);
3993 if (getLexer().isNot(AsmToken::EndOfStatement))
3994 return Error(getLexer().getLoc(),
3995 "unexpected token, expected end of statement");
3996 Parser.Lex(); // Eat EndOfStatement token.
4000 bool MipsAsmParser::parseDirectiveOption() {
4001 MCAsmParser &Parser = getParser();
4002 // Get the option token.
4003 AsmToken Tok = Parser.getTok();
4004 // At the moment only identifiers are supported.
4005 if (Tok.isNot(AsmToken::Identifier)) {
4006 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4007 Parser.eatToEndOfStatement();
4011 StringRef Option = Tok.getIdentifier();
4013 if (Option == "pic0") {
4014 getTargetStreamer().emitDirectiveOptionPic0();
4016 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4017 Error(Parser.getTok().getLoc(),
4018 "unexpected token, expected end of statement");
4019 Parser.eatToEndOfStatement();
4024 if (Option == "pic2") {
4025 getTargetStreamer().emitDirectiveOptionPic2();
4027 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4028 Error(Parser.getTok().getLoc(),
4029 "unexpected token, expected end of statement");
4030 Parser.eatToEndOfStatement();
4036 Warning(Parser.getTok().getLoc(),
4037 "unknown option, expected 'pic0' or 'pic2'");
4038 Parser.eatToEndOfStatement();
4042 /// parseDirectiveModule
4043 /// ::= .module oddspreg
4044 /// ::= .module nooddspreg
4045 /// ::= .module fp=value
4046 bool MipsAsmParser::parseDirectiveModule() {
4047 MCAsmParser &Parser = getParser();
4048 MCAsmLexer &Lexer = getLexer();
4049 SMLoc L = Lexer.getLoc();
4051 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4052 // TODO : get a better message.
4053 reportParseError(".module directive must appear before any code");
4058 if (Parser.parseIdentifier(Option)) {
4059 reportParseError("expected .module option identifier");
4063 if (Option == "oddspreg") {
4064 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4065 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4067 // If this is not the end of the statement, report an error.
4068 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4069 reportParseError("unexpected token, expected end of statement");
4073 return false; // parseDirectiveModule has finished successfully.
4074 } else if (Option == "nooddspreg") {
4076 Error(L, "'.module nooddspreg' requires the O32 ABI");
4080 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4081 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4083 // If this is not the end of the statement, report an error.
4084 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4085 reportParseError("unexpected token, expected end of statement");
4089 return false; // parseDirectiveModule has finished successfully.
4090 } else if (Option == "fp") {
4091 return parseDirectiveModuleFP();
4093 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4097 /// parseDirectiveModuleFP
4101 bool MipsAsmParser::parseDirectiveModuleFP() {
4102 MCAsmParser &Parser = getParser();
4103 MCAsmLexer &Lexer = getLexer();
4105 if (Lexer.isNot(AsmToken::Equal)) {
4106 reportParseError("unexpected token, expected equals sign '='");
4109 Parser.Lex(); // Eat '=' token.
4111 MipsABIFlagsSection::FpABIKind FpABI;
4112 if (!parseFpABIValue(FpABI, ".module"))
4115 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4116 reportParseError("unexpected token, expected end of statement");
4120 // Emit appropriate flags.
4121 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4122 Parser.Lex(); // Consume the EndOfStatement.
4126 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4127 StringRef Directive) {
4128 MCAsmParser &Parser = getParser();
4129 MCAsmLexer &Lexer = getLexer();
4131 if (Lexer.is(AsmToken::Identifier)) {
4132 StringRef Value = Parser.getTok().getString();
4135 if (Value != "xx") {
4136 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4141 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4145 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4149 if (Lexer.is(AsmToken::Integer)) {
4150 unsigned Value = Parser.getTok().getIntVal();
4153 if (Value != 32 && Value != 64) {
4154 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4160 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4164 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4166 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4174 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4175 MCAsmParser &Parser = getParser();
4176 StringRef IDVal = DirectiveID.getString();
4178 if (IDVal == ".cpload")
4179 return parseDirectiveCpLoad(DirectiveID.getLoc());
4180 if (IDVal == ".dword") {
4181 parseDataDirective(8, DirectiveID.getLoc());
4184 if (IDVal == ".ent") {
4185 StringRef SymbolName;
4187 if (Parser.parseIdentifier(SymbolName)) {
4188 reportParseError("expected identifier after .ent");
4192 // There's an undocumented extension that allows an integer to
4193 // follow the name of the procedure which AFAICS is ignored by GAS.
4194 // Example: .ent foo,2
4195 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4196 if (getLexer().isNot(AsmToken::Comma)) {
4197 // Even though we accept this undocumented extension for compatibility
4198 // reasons, the additional integer argument does not actually change
4199 // the behaviour of the '.ent' directive, so we would like to discourage
4200 // its use. We do this by not referring to the extended version in
4201 // error messages which are not directly related to its use.
4202 reportParseError("unexpected token, expected end of statement");
4205 Parser.Lex(); // Eat the comma.
4206 const MCExpr *DummyNumber;
4207 int64_t DummyNumberVal;
4208 // If the user was explicitly trying to use the extended version,
4209 // we still give helpful extension-related error messages.
4210 if (Parser.parseExpression(DummyNumber)) {
4211 reportParseError("expected number after comma");
4214 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4215 reportParseError("expected an absolute expression after comma");
4220 // If this is not the end of the statement, report an error.
4221 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4222 reportParseError("unexpected token, expected end of statement");
4226 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4228 getTargetStreamer().emitDirectiveEnt(*Sym);
4233 if (IDVal == ".end") {
4234 StringRef SymbolName;
4236 if (Parser.parseIdentifier(SymbolName)) {
4237 reportParseError("expected identifier after .end");
4241 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4242 reportParseError("unexpected token, expected end of statement");
4246 if (CurrentFn == nullptr) {
4247 reportParseError(".end used without .ent");
4251 if ((SymbolName != CurrentFn->getName())) {
4252 reportParseError(".end symbol does not match .ent symbol");
4256 getTargetStreamer().emitDirectiveEnd(SymbolName);
4257 CurrentFn = nullptr;
4261 if (IDVal == ".frame") {
4262 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4263 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4264 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4265 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4266 reportParseError("expected stack register");
4270 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4271 if (!StackRegOpnd.isGPRAsmReg()) {
4272 reportParseError(StackRegOpnd.getStartLoc(),
4273 "expected general purpose register");
4276 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4278 if (Parser.getTok().is(AsmToken::Comma))
4281 reportParseError("unexpected token, expected comma");
4285 // Parse the frame size.
4286 const MCExpr *FrameSize;
4287 int64_t FrameSizeVal;
4289 if (Parser.parseExpression(FrameSize)) {
4290 reportParseError("expected frame size value");
4294 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4295 reportParseError("frame size not an absolute expression");
4299 if (Parser.getTok().is(AsmToken::Comma))
4302 reportParseError("unexpected token, expected comma");
4306 // Parse the return register.
4308 ResTy = parseAnyRegister(TmpReg);
4309 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4310 reportParseError("expected return register");
4314 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4315 if (!ReturnRegOpnd.isGPRAsmReg()) {
4316 reportParseError(ReturnRegOpnd.getStartLoc(),
4317 "expected general purpose register");
4321 // If this is not the end of the statement, report an error.
4322 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4323 reportParseError("unexpected token, expected end of statement");
4327 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4328 ReturnRegOpnd.getGPR32Reg());
4332 if (IDVal == ".set") {
4333 return parseDirectiveSet();
4336 if (IDVal == ".mask" || IDVal == ".fmask") {
4337 // .mask bitmask, frame_offset
4338 // bitmask: One bit for each register used.
4339 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4340 // first register is expected to be saved.
4342 // .mask 0x80000000, -4
4343 // .fmask 0x80000000, -4
4346 // Parse the bitmask
4347 const MCExpr *BitMask;
4350 if (Parser.parseExpression(BitMask)) {
4351 reportParseError("expected bitmask value");
4355 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4356 reportParseError("bitmask not an absolute expression");
4360 if (Parser.getTok().is(AsmToken::Comma))
4363 reportParseError("unexpected token, expected comma");
4367 // Parse the frame_offset
4368 const MCExpr *FrameOffset;
4369 int64_t FrameOffsetVal;
4371 if (Parser.parseExpression(FrameOffset)) {
4372 reportParseError("expected frame offset value");
4376 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4377 reportParseError("frame offset not an absolute expression");
4381 // If this is not the end of the statement, report an error.
4382 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4383 reportParseError("unexpected token, expected end of statement");
4387 if (IDVal == ".mask")
4388 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4390 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4394 if (IDVal == ".nan")
4395 return parseDirectiveNaN();
4397 if (IDVal == ".gpword") {
4398 parseDirectiveGpWord();
4402 if (IDVal == ".gpdword") {
4403 parseDirectiveGpDWord();
4407 if (IDVal == ".word") {
4408 parseDataDirective(4, DirectiveID.getLoc());
4412 if (IDVal == ".option")
4413 return parseDirectiveOption();
4415 if (IDVal == ".abicalls") {
4416 getTargetStreamer().emitDirectiveAbiCalls();
4417 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4418 Error(Parser.getTok().getLoc(),
4419 "unexpected token, expected end of statement");
4421 Parser.eatToEndOfStatement();
4426 if (IDVal == ".cpsetup")
4427 return parseDirectiveCPSetup();
4429 if (IDVal == ".module")
4430 return parseDirectiveModule();
4435 extern "C" void LLVMInitializeMipsAsmParser() {
4436 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4437 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4438 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4439 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4442 #define GET_REGISTER_MATCHER
4443 #define GET_MATCHER_IMPLEMENTATION
4444 #include "MipsGenAsmMatcher.inc"