1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(uint64_t Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegIndex();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegIndex() const { return ATReg; }
57 bool setATRegIndex(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 uint64_t getFeatures() const { return Features; }
74 void setFeatures(uint64_t Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const uint64_t AllArchRelatedMask =
82 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
83 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
84 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
85 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
86 Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
87 Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
88 Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
89 Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
100 class MipsAsmParser : public MCTargetAsmParser {
101 MipsTargetStreamer &getTargetStreamer() {
102 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
103 return static_cast<MipsTargetStreamer &>(TS);
106 MCSubtargetInfo &STI;
108 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
109 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
110 // nullptr, which indicates that no function is currently
111 // selected. This usually happens after an '.end func'
114 // Print a warning along with its fix-it message at the given range.
115 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
116 SMRange Range, bool ShowColors = true);
118 #define GET_ASSEMBLER_HEADER
119 #include "MipsGenAsmMatcher.inc"
121 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
123 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
124 OperandVector &Operands, MCStreamer &Out,
126 bool MatchingInlineAsm) override;
128 /// Parse a register as used in CFI directives
129 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
131 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
133 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
135 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
136 SMLoc NameLoc, OperandVector &Operands) override;
138 bool ParseDirective(AsmToken DirectiveID) override;
140 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
142 MipsAsmParser::OperandMatchResultTy
143 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
144 StringRef Identifier, SMLoc S);
146 MipsAsmParser::OperandMatchResultTy
147 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
151 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
153 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy
160 parseRegisterPair (OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseMovePRegPair(OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseRegisterList (OperandVector &Operands);
168 bool searchSymbolAlias(OperandVector &Operands);
170 bool parseOperand(OperandVector &, StringRef Mnemonic);
172 bool needsExpansion(MCInst &Inst);
174 // Expands assembly pseudo instructions.
175 // Returns false on success, true otherwise.
176 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
190 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
200 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
203 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 bool reportParseError(Twine ErrorMsg);
207 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
209 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
210 bool parseRelocOperand(const MCExpr *&Res);
212 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
214 bool isEvaluated(const MCExpr *Expr);
215 bool parseSetMips0Directive();
216 bool parseSetArchDirective();
217 bool parseSetFeature(uint64_t Feature);
218 bool parseDirectiveCpLoad(SMLoc Loc);
219 bool parseDirectiveCPSetup();
220 bool parseDirectiveNaN();
221 bool parseDirectiveSet();
222 bool parseDirectiveOption();
223 bool parseInsnDirective();
225 bool parseSetAtDirective();
226 bool parseSetNoAtDirective();
227 bool parseSetMacroDirective();
228 bool parseSetNoMacroDirective();
229 bool parseSetMsaDirective();
230 bool parseSetNoMsaDirective();
231 bool parseSetNoDspDirective();
232 bool parseSetReorderDirective();
233 bool parseSetNoReorderDirective();
234 bool parseSetMips16Directive();
235 bool parseSetNoMips16Directive();
236 bool parseSetFpDirective();
237 bool parseSetPopDirective();
238 bool parseSetPushDirective();
240 bool parseSetAssignment();
242 bool parseDataDirective(unsigned Size, SMLoc L);
243 bool parseDirectiveGpWord();
244 bool parseDirectiveGpDWord();
245 bool parseDirectiveModule();
246 bool parseDirectiveModuleFP();
247 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
248 StringRef Directive);
250 bool parseInternalDirectiveReallowModule();
252 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
254 bool eatComma(StringRef ErrorStr);
256 int matchCPURegisterName(StringRef Symbol);
258 int matchHWRegsRegisterName(StringRef Symbol);
260 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
262 int matchFPURegisterName(StringRef Name);
264 int matchFCCRegisterName(StringRef Name);
266 int matchACRegisterName(StringRef Name);
268 int matchMSA128RegisterName(StringRef Name);
270 int matchMSA128CtrlRegisterName(StringRef Name);
272 unsigned getReg(int RC, int RegNo);
274 unsigned getGPR(int RegNo);
276 /// Returns the internal register number for the current AT. Also checks if
277 /// the current AT is unavailable (set to $0) and gives an error if it is.
278 /// This should be used in pseudo-instruction expansions which need AT.
279 unsigned getATReg(SMLoc Loc);
281 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
282 SmallVectorImpl<MCInst> &Instructions);
284 // Helper function that checks if the value of a vector index is within the
285 // boundaries of accepted values for each RegisterKind
286 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
287 bool validateMSAIndex(int Val, int RegKind);
289 // Selects a new architecture by updating the FeatureBits with the necessary
290 // info including implied dependencies.
291 // Internally, it clears all the feature bits related to *any* architecture
292 // and selects the new one using the ToggleFeature functionality of the
293 // MCSubtargetInfo object that handles implied dependencies. The reason we
294 // clear all the arch related bits manually is because ToggleFeature only
295 // clears the features that imply the feature being cleared and not the
296 // features implied by the feature being cleared. This is easier to see
298 // --------------------------------------------------
299 // | Feature | Implies |
300 // | -------------------------------------------------|
301 // | FeatureMips1 | None |
302 // | FeatureMips2 | FeatureMips1 |
303 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
304 // | FeatureMips4 | FeatureMips3 |
306 // --------------------------------------------------
308 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
309 // FeatureMipsGP64 | FeatureMips1)
310 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
311 void selectArch(StringRef ArchFeature) {
312 uint64_t FeatureBits = STI.getFeatureBits();
313 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
314 STI.setFeatureBits(FeatureBits);
315 setAvailableFeatures(
316 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
317 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
320 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
321 if (!(STI.getFeatureBits() & Feature)) {
322 setAvailableFeatures(
323 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
325 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
328 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
329 if (STI.getFeatureBits() & Feature) {
330 setAvailableFeatures(
331 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
333 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
337 enum MipsMatchResultTy {
338 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
339 #define GET_OPERAND_DIAGNOSTIC_TYPES
340 #include "MipsGenAsmMatcher.inc"
341 #undef GET_OPERAND_DIAGNOSTIC_TYPES
345 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
346 const MCInstrInfo &MII, const MCTargetOptions &Options)
347 : MCTargetAsmParser(), STI(sti),
348 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
349 sti.getCPU(), Options)) {
350 MCAsmParserExtension::Initialize(parser);
352 parser.addAliasForDirective(".asciiz", ".asciz");
354 // Initialize the set of available features.
355 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
357 // Remember the initial assembler options. The user can not modify these.
358 AssemblerOptions.push_back(
359 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
361 // Create an assembler options environment for the user to modify.
362 AssemblerOptions.push_back(
363 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
365 getTargetStreamer().updateABIInfo(*this);
367 if (!isABI_O32() && !useOddSPReg() != 0)
368 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
373 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
374 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
376 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
377 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
378 const MipsABIInfo &getABI() const { return ABI; }
379 bool isABI_N32() const { return ABI.IsN32(); }
380 bool isABI_N64() const { return ABI.IsN64(); }
381 bool isABI_O32() const { return ABI.IsO32(); }
382 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
384 bool useOddSPReg() const {
385 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
388 bool inMicroMipsMode() const {
389 return STI.getFeatureBits() & Mips::FeatureMicroMips;
391 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
392 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
393 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
394 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
395 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
396 bool hasMips32() const {
397 return (STI.getFeatureBits() & Mips::FeatureMips32);
399 bool hasMips64() const {
400 return (STI.getFeatureBits() & Mips::FeatureMips64);
402 bool hasMips32r2() const {
403 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
405 bool hasMips64r2() const {
406 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
408 bool hasMips32r3() const {
409 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
411 bool hasMips64r3() const {
412 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
414 bool hasMips32r5() const {
415 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
417 bool hasMips64r5() const {
418 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
420 bool hasMips32r6() const {
421 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
423 bool hasMips64r6() const {
424 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
426 bool hasCnMips() const {
427 return (STI.getFeatureBits() & Mips::FeatureCnMips);
429 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
430 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
431 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
433 bool inMips16Mode() const {
434 return STI.getFeatureBits() & Mips::FeatureMips16;
436 // TODO: see how can we get this info.
437 bool abiUsesSoftFloat() const { return false; }
439 /// Warn if RegIndex is the same as the current AT.
440 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
446 /// MipsOperand - Instances of this class represent a parsed Mips machine
448 class MipsOperand : public MCParsedAsmOperand {
450 /// Broad categories of register classes
451 /// The exact class is finalized by the render method.
453 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
454 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
456 RegKind_FCC = 4, /// FCC
457 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
458 RegKind_MSACtrl = 16, /// MSA control registers
459 RegKind_COP2 = 32, /// COP2
460 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
462 RegKind_CCR = 128, /// CCR
463 RegKind_HWRegs = 256, /// HWRegs
464 RegKind_COP3 = 512, /// COP3
466 /// Potentially any (e.g. $1)
467 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
468 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
469 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
474 k_Immediate, /// An immediate (possibly involving symbol references)
475 k_Memory, /// Base + Offset Memory Address
476 k_PhysRegister, /// A physical register from the Mips namespace
477 k_RegisterIndex, /// A register index in one or more RegKind.
478 k_Token, /// A simple token
479 k_RegList, /// A physical register list
480 k_RegPair /// A pair of physical register
484 MipsOperand(KindTy K, MipsAsmParser &Parser)
485 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
488 /// For diagnostics, and checking the assembler temporary
489 MipsAsmParser &AsmParser;
497 unsigned Num; /// Register Number
501 unsigned Index; /// Index into the register class
502 RegKind Kind; /// Bitfield of the kinds it could possibly be
503 const MCRegisterInfo *RegInfo;
516 SmallVector<unsigned, 10> *List;
521 struct PhysRegOp PhysReg;
522 struct RegIdxOp RegIdx;
525 struct RegListOp RegList;
528 SMLoc StartLoc, EndLoc;
530 /// Internal constructor for register kinds
531 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
532 const MCRegisterInfo *RegInfo,
534 MipsAsmParser &Parser) {
535 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
536 Op->RegIdx.Index = Index;
537 Op->RegIdx.RegInfo = RegInfo;
538 Op->RegIdx.Kind = RegKind;
545 /// Coerce the register to GPR32 and return the real register for the current
547 unsigned getGPR32Reg() const {
548 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
549 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
550 unsigned ClassID = Mips::GPR32RegClassID;
551 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
554 /// Coerce the register to GPR32 and return the real register for the current
556 unsigned getGPRMM16Reg() const {
557 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
558 unsigned ClassID = Mips::GPR32RegClassID;
559 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
562 /// Coerce the register to GPR64 and return the real register for the current
564 unsigned getGPR64Reg() const {
565 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
566 unsigned ClassID = Mips::GPR64RegClassID;
567 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
571 /// Coerce the register to AFGR64 and return the real register for the current
573 unsigned getAFGR64Reg() const {
574 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
575 if (RegIdx.Index % 2 != 0)
576 AsmParser.Warning(StartLoc, "Float register should be even.");
577 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
578 .getRegister(RegIdx.Index / 2);
581 /// Coerce the register to FGR64 and return the real register for the current
583 unsigned getFGR64Reg() const {
584 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
585 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
586 .getRegister(RegIdx.Index);
589 /// Coerce the register to FGR32 and return the real register for the current
591 unsigned getFGR32Reg() const {
592 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
593 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
594 .getRegister(RegIdx.Index);
597 /// Coerce the register to FGRH32 and return the real register for the current
599 unsigned getFGRH32Reg() const {
600 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
601 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
602 .getRegister(RegIdx.Index);
605 /// Coerce the register to FCC and return the real register for the current
607 unsigned getFCCReg() const {
608 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
609 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
610 .getRegister(RegIdx.Index);
613 /// Coerce the register to MSA128 and return the real register for the current
615 unsigned getMSA128Reg() const {
616 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
617 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
619 unsigned ClassID = Mips::MSA128BRegClassID;
620 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
623 /// Coerce the register to MSACtrl and return the real register for the
625 unsigned getMSACtrlReg() const {
626 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
627 unsigned ClassID = Mips::MSACtrlRegClassID;
628 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
631 /// Coerce the register to COP2 and return the real register for the
633 unsigned getCOP2Reg() const {
634 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
635 unsigned ClassID = Mips::COP2RegClassID;
636 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
639 /// Coerce the register to COP3 and return the real register for the
641 unsigned getCOP3Reg() const {
642 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
643 unsigned ClassID = Mips::COP3RegClassID;
644 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
647 /// Coerce the register to ACC64DSP and return the real register for the
649 unsigned getACC64DSPReg() const {
650 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
651 unsigned ClassID = Mips::ACC64DSPRegClassID;
652 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
655 /// Coerce the register to HI32DSP and return the real register for the
657 unsigned getHI32DSPReg() const {
658 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
659 unsigned ClassID = Mips::HI32DSPRegClassID;
660 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
663 /// Coerce the register to LO32DSP and return the real register for the
665 unsigned getLO32DSPReg() const {
666 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
667 unsigned ClassID = Mips::LO32DSPRegClassID;
668 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
671 /// Coerce the register to CCR and return the real register for the
673 unsigned getCCRReg() const {
674 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
675 unsigned ClassID = Mips::CCRRegClassID;
676 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
679 /// Coerce the register to HWRegs and return the real register for the
681 unsigned getHWRegsReg() const {
682 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
683 unsigned ClassID = Mips::HWRegsRegClassID;
684 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
688 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
689 // Add as immediate when possible. Null MCExpr = 0.
691 Inst.addOperand(MCOperand::CreateImm(0));
692 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
693 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
695 Inst.addOperand(MCOperand::CreateExpr(Expr));
698 void addRegOperands(MCInst &Inst, unsigned N) const {
699 llvm_unreachable("Use a custom parser instead");
702 /// Render the operand to an MCInst as a GPR32
703 /// Asserts if the wrong number of operands are requested, or the operand
704 /// is not a k_RegisterIndex compatible with RegKind_GPR
705 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
706 assert(N == 1 && "Invalid number of operands!");
707 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
710 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
711 assert(N == 1 && "Invalid number of operands!");
712 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
715 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
716 assert(N == 1 && "Invalid number of operands!");
717 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
720 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
721 assert(N == 1 && "Invalid number of operands!");
722 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
725 /// Render the operand to an MCInst as a GPR64
726 /// Asserts if the wrong number of operands are requested, or the operand
727 /// is not a k_RegisterIndex compatible with RegKind_GPR
728 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
729 assert(N == 1 && "Invalid number of operands!");
730 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
733 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
734 assert(N == 1 && "Invalid number of operands!");
735 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
738 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
739 assert(N == 1 && "Invalid number of operands!");
740 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
743 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
744 assert(N == 1 && "Invalid number of operands!");
745 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
746 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
747 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
748 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
752 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
753 assert(N == 1 && "Invalid number of operands!");
754 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
757 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
758 assert(N == 1 && "Invalid number of operands!");
759 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
762 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
763 assert(N == 1 && "Invalid number of operands!");
764 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
767 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
768 assert(N == 1 && "Invalid number of operands!");
769 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
772 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
773 assert(N == 1 && "Invalid number of operands!");
774 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
777 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
778 assert(N == 1 && "Invalid number of operands!");
779 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
782 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
783 assert(N == 1 && "Invalid number of operands!");
784 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
787 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
788 assert(N == 1 && "Invalid number of operands!");
789 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
792 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
793 assert(N == 1 && "Invalid number of operands!");
794 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
797 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
798 assert(N == 1 && "Invalid number of operands!");
799 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
802 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
803 assert(N == 1 && "Invalid number of operands!");
804 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
807 void addImmOperands(MCInst &Inst, unsigned N) const {
808 assert(N == 1 && "Invalid number of operands!");
809 const MCExpr *Expr = getImm();
813 void addMemOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 2 && "Invalid number of operands!");
816 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
818 const MCExpr *Expr = getMemOff();
822 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 2 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
827 const MCExpr *Expr = getMemOff();
831 void addRegListOperands(MCInst &Inst, unsigned N) const {
832 assert(N == 1 && "Invalid number of operands!");
834 for (auto RegNo : getRegList())
835 Inst.addOperand(MCOperand::CreateReg(RegNo));
838 void addRegPairOperands(MCInst &Inst, unsigned N) const {
839 assert(N == 2 && "Invalid number of operands!");
840 unsigned RegNo = getRegPair();
841 Inst.addOperand(MCOperand::CreateReg(RegNo++));
842 Inst.addOperand(MCOperand::CreateReg(RegNo));
845 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
846 assert(N == 2 && "Invalid number of operands!");
847 for (auto RegNo : getRegList())
848 Inst.addOperand(MCOperand::CreateReg(RegNo));
851 bool isReg() const override {
852 // As a special case until we sort out the definition of div/divu, pretend
853 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
854 if (isGPRAsmReg() && RegIdx.Index == 0)
857 return Kind == k_PhysRegister;
859 bool isRegIdx() const { return Kind == k_RegisterIndex; }
860 bool isImm() const override { return Kind == k_Immediate; }
861 bool isConstantImm() const {
862 return isImm() && dyn_cast<MCConstantExpr>(getImm());
864 bool isToken() const override {
865 // Note: It's not possible to pretend that other operand kinds are tokens.
866 // The matcher emitter checks tokens first.
867 return Kind == k_Token;
869 bool isMem() const override { return Kind == k_Memory; }
870 bool isConstantMemOff() const {
871 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
873 template <unsigned Bits> bool isMemWithSimmOffset() const {
874 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
876 bool isMemWithGRPMM16Base() const {
877 return isMem() && getMemBase()->isMM16AsmReg();
879 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
880 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
881 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
883 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
884 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
885 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
886 && (getMemBase()->getGPR32Reg() == Mips::SP);
888 bool isRegList16() const {
892 int Size = RegList.List->size();
893 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
894 RegList.List->back() != Mips::RA)
897 int PrevReg = *RegList.List->begin();
898 for (int i = 1; i < Size - 1; i++) {
899 int Reg = (*(RegList.List))[i];
900 if ( Reg != PrevReg + 1)
907 bool isInvNum() const { return Kind == k_Immediate; }
908 bool isLSAImm() const {
909 if (!isConstantImm())
911 int64_t Val = getConstantImm();
912 return 1 <= Val && Val <= 4;
914 bool isRegList() const { return Kind == k_RegList; }
915 bool isMovePRegPair() const {
916 if (Kind != k_RegList || RegList.List->size() != 2)
919 unsigned R0 = RegList.List->front();
920 unsigned R1 = RegList.List->back();
922 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
923 (R0 == Mips::A1 && R1 == Mips::A3) ||
924 (R0 == Mips::A2 && R1 == Mips::A3) ||
925 (R0 == Mips::A0 && R1 == Mips::S5) ||
926 (R0 == Mips::A0 && R1 == Mips::S6) ||
927 (R0 == Mips::A0 && R1 == Mips::A1) ||
928 (R0 == Mips::A0 && R1 == Mips::A2) ||
929 (R0 == Mips::A0 && R1 == Mips::A3))
935 StringRef getToken() const {
936 assert(Kind == k_Token && "Invalid access!");
937 return StringRef(Tok.Data, Tok.Length);
939 bool isRegPair() const { return Kind == k_RegPair; }
941 unsigned getReg() const override {
942 // As a special case until we sort out the definition of div/divu, pretend
943 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
944 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
945 RegIdx.Kind & RegKind_GPR)
946 return getGPR32Reg(); // FIXME: GPR64 too
948 assert(Kind == k_PhysRegister && "Invalid access!");
952 const MCExpr *getImm() const {
953 assert((Kind == k_Immediate) && "Invalid access!");
957 int64_t getConstantImm() const {
958 const MCExpr *Val = getImm();
959 return static_cast<const MCConstantExpr *>(Val)->getValue();
962 MipsOperand *getMemBase() const {
963 assert((Kind == k_Memory) && "Invalid access!");
967 const MCExpr *getMemOff() const {
968 assert((Kind == k_Memory) && "Invalid access!");
972 int64_t getConstantMemOff() const {
973 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
976 const SmallVectorImpl<unsigned> &getRegList() const {
977 assert((Kind == k_RegList) && "Invalid access!");
978 return *(RegList.List);
981 unsigned getRegPair() const {
982 assert((Kind == k_RegPair) && "Invalid access!");
986 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
987 MipsAsmParser &Parser) {
988 auto Op = make_unique<MipsOperand>(k_Token, Parser);
989 Op->Tok.Data = Str.data();
990 Op->Tok.Length = Str.size();
996 /// Create a numeric register (e.g. $1). The exact register remains
997 /// unresolved until an instruction successfully matches
998 static std::unique_ptr<MipsOperand>
999 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1000 SMLoc E, MipsAsmParser &Parser) {
1001 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1002 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1005 /// Create a register that is definitely a GPR.
1006 /// This is typically only used for named registers such as $gp.
1007 static std::unique_ptr<MipsOperand>
1008 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1009 MipsAsmParser &Parser) {
1010 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1013 /// Create a register that is definitely a FGR.
1014 /// This is typically only used for named registers such as $f0.
1015 static std::unique_ptr<MipsOperand>
1016 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1017 MipsAsmParser &Parser) {
1018 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1021 /// Create a register that is definitely a HWReg.
1022 /// This is typically only used for named registers such as $hwr_cpunum.
1023 static std::unique_ptr<MipsOperand>
1024 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1025 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1026 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1029 /// Create a register that is definitely an FCC.
1030 /// This is typically only used for named registers such as $fcc0.
1031 static std::unique_ptr<MipsOperand>
1032 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1033 MipsAsmParser &Parser) {
1034 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1037 /// Create a register that is definitely an ACC.
1038 /// This is typically only used for named registers such as $ac0.
1039 static std::unique_ptr<MipsOperand>
1040 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1041 MipsAsmParser &Parser) {
1042 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1045 /// Create a register that is definitely an MSA128.
1046 /// This is typically only used for named registers such as $w0.
1047 static std::unique_ptr<MipsOperand>
1048 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1049 SMLoc E, MipsAsmParser &Parser) {
1050 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1053 /// Create a register that is definitely an MSACtrl.
1054 /// This is typically only used for named registers such as $msaaccess.
1055 static std::unique_ptr<MipsOperand>
1056 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1057 SMLoc E, MipsAsmParser &Parser) {
1058 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1061 static std::unique_ptr<MipsOperand>
1062 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1063 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1070 static std::unique_ptr<MipsOperand>
1071 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1072 SMLoc E, MipsAsmParser &Parser) {
1073 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1074 Op->Mem.Base = Base.release();
1081 static std::unique_ptr<MipsOperand>
1082 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1083 MipsAsmParser &Parser) {
1084 assert (Regs.size() > 0 && "Empty list not allowed");
1086 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1087 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1088 Op->StartLoc = StartLoc;
1089 Op->EndLoc = EndLoc;
1093 static std::unique_ptr<MipsOperand>
1094 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1095 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1096 Op->RegIdx.Index = RegNo;
1102 bool isGPRAsmReg() const {
1103 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1105 bool isMM16AsmReg() const {
1106 if (!(isRegIdx() && RegIdx.Kind))
1108 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1109 || RegIdx.Index == 16 || RegIdx.Index == 17);
1111 bool isMM16AsmRegZero() const {
1112 if (!(isRegIdx() && RegIdx.Kind))
1114 return (RegIdx.Index == 0 ||
1115 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1116 RegIdx.Index == 17);
1118 bool isMM16AsmRegMoveP() const {
1119 if (!(isRegIdx() && RegIdx.Kind))
1121 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1122 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1124 bool isFGRAsmReg() const {
1125 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1126 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1128 bool isHWRegsAsmReg() const {
1129 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1131 bool isCCRAsmReg() const {
1132 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1134 bool isFCCAsmReg() const {
1135 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1137 if (!AsmParser.hasEightFccRegisters())
1138 return RegIdx.Index == 0;
1139 return RegIdx.Index <= 7;
1141 bool isACCAsmReg() const {
1142 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1144 bool isCOP2AsmReg() const {
1145 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1147 bool isCOP3AsmReg() const {
1148 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1150 bool isMSA128AsmReg() const {
1151 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1153 bool isMSACtrlAsmReg() const {
1154 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1157 /// getStartLoc - Get the location of the first token of this operand.
1158 SMLoc getStartLoc() const override { return StartLoc; }
1159 /// getEndLoc - Get the location of the last token of this operand.
1160 SMLoc getEndLoc() const override { return EndLoc; }
1162 virtual ~MipsOperand() {
1170 delete RegList.List;
1171 case k_PhysRegister:
1172 case k_RegisterIndex:
1179 void print(raw_ostream &OS) const override {
1188 Mem.Base->print(OS);
1193 case k_PhysRegister:
1194 OS << "PhysReg<" << PhysReg.Num << ">";
1196 case k_RegisterIndex:
1197 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1204 for (auto Reg : (*RegList.List))
1209 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1213 }; // class MipsOperand
1217 extern const MCInstrDesc MipsInsts[];
1219 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1220 return MipsInsts[Opcode];
1223 static bool hasShortDelaySlot(unsigned Opcode) {
1226 case Mips::JALRS_MM:
1227 case Mips::JALRS16_MM:
1228 case Mips::BGEZALS_MM:
1229 case Mips::BLTZALS_MM:
1236 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1237 SmallVectorImpl<MCInst> &Instructions) {
1238 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1242 if (MCID.isBranch() || MCID.isCall()) {
1243 const unsigned Opcode = Inst.getOpcode();
1253 assert(hasCnMips() && "instruction only valid for octeon cpus");
1260 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1261 Offset = Inst.getOperand(2);
1262 if (!Offset.isImm())
1263 break; // We'll deal with this situation later on when applying fixups.
1264 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1265 return Error(IDLoc, "branch target out of range");
1266 if (OffsetToAlignment(Offset.getImm(),
1267 1LL << (inMicroMipsMode() ? 1 : 2)))
1268 return Error(IDLoc, "branch to misaligned address");
1282 case Mips::BGEZAL_MM:
1283 case Mips::BLTZAL_MM:
1286 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1287 Offset = Inst.getOperand(1);
1288 if (!Offset.isImm())
1289 break; // We'll deal with this situation later on when applying fixups.
1290 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1291 return Error(IDLoc, "branch target out of range");
1292 if (OffsetToAlignment(Offset.getImm(),
1293 1LL << (inMicroMipsMode() ? 1 : 2)))
1294 return Error(IDLoc, "branch to misaligned address");
1296 case Mips::BEQZ16_MM:
1297 case Mips::BNEZ16_MM:
1298 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1299 Offset = Inst.getOperand(1);
1300 if (!Offset.isImm())
1301 break; // We'll deal with this situation later on when applying fixups.
1302 if (!isIntN(8, Offset.getImm()))
1303 return Error(IDLoc, "branch target out of range");
1304 if (OffsetToAlignment(Offset.getImm(), 2LL))
1305 return Error(IDLoc, "branch to misaligned address");
1310 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1311 // We still accept it but it is a normal nop.
1312 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1313 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1314 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1319 const unsigned Opcode = Inst.getOpcode();
1331 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1332 // The offset is handled above
1333 Opnd = Inst.getOperand(1);
1335 return Error(IDLoc, "expected immediate operand kind");
1336 Imm = Opnd.getImm();
1337 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1338 Opcode == Mips::BBIT1 ? 63 : 31))
1339 return Error(IDLoc, "immediate operand value out of range");
1341 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1343 Inst.getOperand(1).setImm(Imm - 32);
1351 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1353 Opnd = Inst.getOperand(3);
1355 return Error(IDLoc, "expected immediate operand kind");
1356 Imm = Opnd.getImm();
1357 if (Imm < 0 || Imm > 31)
1358 return Error(IDLoc, "immediate operand value out of range");
1360 Opnd = Inst.getOperand(2);
1362 return Error(IDLoc, "expected immediate operand kind");
1363 Imm = Opnd.getImm();
1364 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1365 Opcode == Mips::EXTS ? 63 : 31))
1366 return Error(IDLoc, "immediate operand value out of range");
1368 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1369 Inst.getOperand(2).setImm(Imm - 32);
1375 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1376 Opnd = Inst.getOperand(2);
1378 return Error(IDLoc, "expected immediate operand kind");
1379 Imm = Opnd.getImm();
1380 if (!isInt<10>(Imm))
1381 return Error(IDLoc, "immediate operand value out of range");
1386 if (MCID.mayLoad() || MCID.mayStore()) {
1387 // Check the offset of memory operand, if it is a symbol
1388 // reference or immediate we may have to expand instructions.
1389 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1390 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1391 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1392 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1393 MCOperand &Op = Inst.getOperand(i);
1395 int MemOffset = Op.getImm();
1396 if (MemOffset < -32768 || MemOffset > 32767) {
1397 // Offset can't exceed 16bit value.
1398 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1401 } else if (Op.isExpr()) {
1402 const MCExpr *Expr = Op.getExpr();
1403 if (Expr->getKind() == MCExpr::SymbolRef) {
1404 const MCSymbolRefExpr *SR =
1405 static_cast<const MCSymbolRefExpr *>(Expr);
1406 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1408 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1411 } else if (!isEvaluated(Expr)) {
1412 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1420 if (inMicroMipsMode()) {
1421 if (MCID.mayLoad()) {
1422 // Try to create 16-bit GP relative load instruction.
1423 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1424 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1425 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1426 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1427 MCOperand &Op = Inst.getOperand(i);
1429 int MemOffset = Op.getImm();
1430 MCOperand &DstReg = Inst.getOperand(0);
1431 MCOperand &BaseReg = Inst.getOperand(1);
1432 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1433 getContext().getRegisterInfo()->getRegClass(
1434 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1435 BaseReg.getReg() == Mips::GP) {
1437 TmpInst.setLoc(IDLoc);
1438 TmpInst.setOpcode(Mips::LWGP_MM);
1439 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1440 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1441 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1442 Instructions.push_back(TmpInst);
1450 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1455 switch (Inst.getOpcode()) {
1458 case Mips::ADDIUS5_MM:
1459 Opnd = Inst.getOperand(2);
1461 return Error(IDLoc, "expected immediate operand kind");
1462 Imm = Opnd.getImm();
1463 if (Imm < -8 || Imm > 7)
1464 return Error(IDLoc, "immediate operand value out of range");
1466 case Mips::ADDIUSP_MM:
1467 Opnd = Inst.getOperand(0);
1469 return Error(IDLoc, "expected immediate operand kind");
1470 Imm = Opnd.getImm();
1471 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1473 return Error(IDLoc, "immediate operand value out of range");
1475 case Mips::SLL16_MM:
1476 case Mips::SRL16_MM:
1477 Opnd = Inst.getOperand(2);
1479 return Error(IDLoc, "expected immediate operand kind");
1480 Imm = Opnd.getImm();
1481 if (Imm < 1 || Imm > 8)
1482 return Error(IDLoc, "immediate operand value out of range");
1485 Opnd = Inst.getOperand(1);
1487 return Error(IDLoc, "expected immediate operand kind");
1488 Imm = Opnd.getImm();
1489 if (Imm < -1 || Imm > 126)
1490 return Error(IDLoc, "immediate operand value out of range");
1492 case Mips::ADDIUR2_MM:
1493 Opnd = Inst.getOperand(2);
1495 return Error(IDLoc, "expected immediate operand kind");
1496 Imm = Opnd.getImm();
1497 if (!(Imm == 1 || Imm == -1 ||
1498 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1499 return Error(IDLoc, "immediate operand value out of range");
1501 case Mips::ADDIUR1SP_MM:
1502 Opnd = Inst.getOperand(1);
1504 return Error(IDLoc, "expected immediate operand kind");
1505 Imm = Opnd.getImm();
1506 if (OffsetToAlignment(Imm, 4LL))
1507 return Error(IDLoc, "misaligned immediate operand value");
1508 if (Imm < 0 || Imm > 255)
1509 return Error(IDLoc, "immediate operand value out of range");
1511 case Mips::ANDI16_MM:
1512 Opnd = Inst.getOperand(2);
1514 return Error(IDLoc, "expected immediate operand kind");
1515 Imm = Opnd.getImm();
1516 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1517 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1518 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1519 return Error(IDLoc, "immediate operand value out of range");
1521 case Mips::LBU16_MM:
1522 Opnd = Inst.getOperand(2);
1524 return Error(IDLoc, "expected immediate operand kind");
1525 Imm = Opnd.getImm();
1526 if (Imm < -1 || Imm > 14)
1527 return Error(IDLoc, "immediate operand value out of range");
1530 Opnd = Inst.getOperand(2);
1532 return Error(IDLoc, "expected immediate operand kind");
1533 Imm = Opnd.getImm();
1534 if (Imm < 0 || Imm > 15)
1535 return Error(IDLoc, "immediate operand value out of range");
1537 case Mips::LHU16_MM:
1539 Opnd = Inst.getOperand(2);
1541 return Error(IDLoc, "expected immediate operand kind");
1542 Imm = Opnd.getImm();
1543 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1544 return Error(IDLoc, "immediate operand value out of range");
1548 Opnd = Inst.getOperand(2);
1550 return Error(IDLoc, "expected immediate operand kind");
1551 Imm = Opnd.getImm();
1552 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1553 return Error(IDLoc, "immediate operand value out of range");
1557 Opnd = Inst.getOperand(2);
1559 return Error(IDLoc, "expected immediate operand kind");
1560 Imm = Opnd.getImm();
1561 if (!isUInt<5>(Imm))
1562 return Error(IDLoc, "immediate operand value out of range");
1564 case Mips::ADDIUPC_MM:
1565 MCOperand Opnd = Inst.getOperand(1);
1567 return Error(IDLoc, "expected immediate operand kind");
1568 int Imm = Opnd.getImm();
1569 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1570 return Error(IDLoc, "immediate operand value out of range");
1575 if (needsExpansion(Inst)) {
1576 if (expandInstruction(Inst, IDLoc, Instructions))
1579 Instructions.push_back(Inst);
1581 // If this instruction has a delay slot and .set reorder is active,
1582 // emit a NOP after it.
1583 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1584 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1589 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1591 switch (Inst.getOpcode()) {
1592 case Mips::LoadImm32:
1593 case Mips::LoadImm64:
1594 case Mips::LoadAddrImm32:
1595 case Mips::LoadAddrReg32:
1596 case Mips::B_MM_Pseudo:
1599 case Mips::JalOneReg:
1600 case Mips::JalTwoReg:
1607 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1608 SmallVectorImpl<MCInst> &Instructions) {
1609 switch (Inst.getOpcode()) {
1610 default: llvm_unreachable("unimplemented expansion");
1611 case Mips::LoadImm32:
1612 return expandLoadImm(Inst, IDLoc, Instructions);
1613 case Mips::LoadImm64:
1615 Error(IDLoc, "instruction requires a 64-bit architecture");
1618 return expandLoadImm(Inst, IDLoc, Instructions);
1619 case Mips::LoadAddrImm32:
1620 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1621 case Mips::LoadAddrReg32:
1622 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1623 case Mips::B_MM_Pseudo:
1624 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1627 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1628 case Mips::JalOneReg:
1629 case Mips::JalTwoReg:
1630 return expandJalWithRegs(Inst, IDLoc, Instructions);
1635 template <bool PerformShift>
1636 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1637 SmallVectorImpl<MCInst> &Instructions) {
1640 tmpInst.setOpcode(Mips::DSLL);
1641 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1642 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1643 tmpInst.addOperand(MCOperand::CreateImm(16));
1644 tmpInst.setLoc(IDLoc);
1645 Instructions.push_back(tmpInst);
1648 // There's no need for an ORi if the immediate is 0.
1649 if (Operand.isImm() && Operand.getImm() == 0)
1652 tmpInst.setOpcode(Mips::ORi);
1653 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1654 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1655 tmpInst.addOperand(Operand);
1656 tmpInst.setLoc(IDLoc);
1657 Instructions.push_back(tmpInst);
1660 template <int Shift, bool PerformShift>
1661 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1662 SmallVectorImpl<MCInst> &Instructions) {
1663 createLShiftOri<PerformShift>(
1664 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1665 IDLoc, Instructions);
1669 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1670 SmallVectorImpl<MCInst> &Instructions) {
1671 // Create a JALR instruction which is going to replace the pseudo-JAL.
1673 JalrInst.setLoc(IDLoc);
1674 const MCOperand FirstRegOp = Inst.getOperand(0);
1675 const unsigned Opcode = Inst.getOpcode();
1677 if (Opcode == Mips::JalOneReg) {
1678 // jal $rs => jalr $rs
1679 if (inMicroMipsMode()) {
1680 JalrInst.setOpcode(Mips::JALR16_MM);
1681 JalrInst.addOperand(FirstRegOp);
1683 JalrInst.setOpcode(Mips::JALR);
1684 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1685 JalrInst.addOperand(FirstRegOp);
1687 } else if (Opcode == Mips::JalTwoReg) {
1688 // jal $rd, $rs => jalr $rd, $rs
1689 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1690 JalrInst.addOperand(FirstRegOp);
1691 const MCOperand SecondRegOp = Inst.getOperand(1);
1692 JalrInst.addOperand(SecondRegOp);
1694 Instructions.push_back(JalrInst);
1696 // If .set reorder is active, emit a NOP after it.
1697 if (AssemblerOptions.back()->isReorder()) {
1698 // This is a 32-bit NOP because these 2 pseudo-instructions
1699 // do not have a short delay slot.
1701 NopInst.setOpcode(Mips::SLL);
1702 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1703 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1704 NopInst.addOperand(MCOperand::CreateImm(0));
1705 Instructions.push_back(NopInst);
1711 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1712 SmallVectorImpl<MCInst> &Instructions) {
1714 const MCOperand &ImmOp = Inst.getOperand(1);
1715 assert(ImmOp.isImm() && "expected immediate operand kind");
1716 const MCOperand &RegOp = Inst.getOperand(0);
1717 assert(RegOp.isReg() && "expected register operand kind");
1719 int64_t ImmValue = ImmOp.getImm();
1720 unsigned Reg = RegOp.getReg();
1721 tmpInst.setLoc(IDLoc);
1722 // FIXME: gas has a special case for values that are 000...1111, which
1723 // becomes a li -1 and then a dsrl
1724 if (0 <= ImmValue && ImmValue <= 65535) {
1725 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1726 // li d,j => ori d,$zero,j
1727 tmpInst.setOpcode(Mips::ORi);
1728 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1729 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1730 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1731 Instructions.push_back(tmpInst);
1732 } else if (ImmValue < 0 && ImmValue >= -32768) {
1733 // For negative signed 16-bit values (-32768 <= j < 0):
1734 // li d,j => addiu d,$zero,j
1735 tmpInst.setOpcode(Mips::ADDiu);
1736 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1737 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1738 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1739 Instructions.push_back(tmpInst);
1740 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1741 // For all other values which are representable as a 32-bit integer:
1742 // li d,j => lui d,hi16(j)
1744 tmpInst.setOpcode(Mips::LUi);
1745 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1746 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1747 Instructions.push_back(tmpInst);
1748 createLShiftOri<0, false>(ImmValue, Reg, IDLoc, Instructions);
1749 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1751 Error(IDLoc, "instruction requires a 64-bit architecture");
1755 // <------- lo32 ------>
1756 // <------- hi32 ------>
1757 // <- hi16 -> <- lo16 ->
1758 // _________________________________
1760 // | 16-bits | 16-bits | 16-bits |
1761 // |__________|__________|__________|
1763 // For any 64-bit value that is representable as a 48-bit integer:
1764 // li d,j => lui d,hi16(j)
1765 // ori d,d,hi16(lo32(j))
1767 // ori d,d,lo16(lo32(j))
1768 tmpInst.setOpcode(Mips::LUi);
1769 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1771 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1772 Instructions.push_back(tmpInst);
1773 createLShiftOri<16, false>(ImmValue, Reg, IDLoc, Instructions);
1774 createLShiftOri<0, true>(ImmValue, Reg, IDLoc, Instructions);
1777 Error(IDLoc, "instruction requires a 64-bit architecture");
1781 // <------- hi32 ------> <------- lo32 ------>
1782 // <- hi16 -> <- lo16 ->
1783 // ___________________________________________
1785 // | 16-bits | 16-bits | 16-bits | 16-bits |
1786 // |__________|__________|__________|__________|
1788 // For all other values which are representable as a 64-bit integer:
1789 // li d,j => lui d,hi16(j)
1790 // ori d,d,lo16(hi32(j))
1792 // ori d,d,hi16(lo32(j))
1794 // ori d,d,lo16(lo32(j))
1795 tmpInst.setOpcode(Mips::LUi);
1796 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1798 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1799 Instructions.push_back(tmpInst);
1800 createLShiftOri<32, false>(ImmValue, Reg, IDLoc, Instructions);
1801 createLShiftOri<16, true>(ImmValue, Reg, IDLoc, Instructions);
1802 createLShiftOri<0, true>(ImmValue, Reg, IDLoc, Instructions);
1808 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1809 SmallVectorImpl<MCInst> &Instructions) {
1811 const MCOperand &ImmOp = Inst.getOperand(2);
1812 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1813 "expected immediate operand kind");
1814 if (!ImmOp.isImm()) {
1815 expandLoadAddressSym(Inst, IDLoc, Instructions);
1818 const MCOperand &SrcRegOp = Inst.getOperand(1);
1819 assert(SrcRegOp.isReg() && "expected register operand kind");
1820 const MCOperand &DstRegOp = Inst.getOperand(0);
1821 assert(DstRegOp.isReg() && "expected register operand kind");
1822 int ImmValue = ImmOp.getImm();
1823 if (-32768 <= ImmValue && ImmValue <= 65535) {
1824 // For -32768 <= j <= 65535.
1825 // la d,j(s) => addiu d,s,j
1826 tmpInst.setOpcode(Mips::ADDiu);
1827 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1828 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1829 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1830 Instructions.push_back(tmpInst);
1832 // For any other value of j that is representable as a 32-bit integer.
1833 // la d,j(s) => lui d,hi16(j)
1836 tmpInst.setOpcode(Mips::LUi);
1837 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1838 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1839 Instructions.push_back(tmpInst);
1841 tmpInst.setOpcode(Mips::ORi);
1842 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1843 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1844 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1845 Instructions.push_back(tmpInst);
1847 tmpInst.setOpcode(Mips::ADDu);
1848 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1849 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1850 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1851 Instructions.push_back(tmpInst);
1857 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1858 SmallVectorImpl<MCInst> &Instructions) {
1860 const MCOperand &ImmOp = Inst.getOperand(1);
1861 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1862 "expected immediate operand kind");
1863 if (!ImmOp.isImm()) {
1864 expandLoadAddressSym(Inst, IDLoc, Instructions);
1867 const MCOperand &RegOp = Inst.getOperand(0);
1868 assert(RegOp.isReg() && "expected register operand kind");
1869 int ImmValue = ImmOp.getImm();
1870 if (-32768 <= ImmValue && ImmValue <= 65535) {
1871 // For -32768 <= j <= 65535.
1872 // la d,j => addiu d,$zero,j
1873 tmpInst.setOpcode(Mips::ADDiu);
1874 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1875 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1876 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1877 Instructions.push_back(tmpInst);
1879 // For any other value of j that is representable as a 32-bit integer.
1880 // la d,j => lui d,hi16(j)
1882 tmpInst.setOpcode(Mips::LUi);
1883 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1884 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1885 Instructions.push_back(tmpInst);
1887 tmpInst.setOpcode(Mips::ORi);
1888 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1889 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1890 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1891 Instructions.push_back(tmpInst);
1897 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1898 SmallVectorImpl<MCInst> &Instructions) {
1899 // FIXME: If we do have a valid at register to use, we should generate a
1900 // slightly shorter sequence here.
1902 int ExprOperandNo = 1;
1903 // Sometimes the assembly parser will get the immediate expression as
1904 // a $zero + an immediate.
1905 if (Inst.getNumOperands() == 3) {
1906 assert(Inst.getOperand(1).getReg() ==
1907 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1910 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1911 assert(SymOp.isExpr() && "expected symbol operand kind");
1912 const MCOperand &RegOp = Inst.getOperand(0);
1913 unsigned RegNo = RegOp.getReg();
1914 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1915 const MCSymbolRefExpr *HiExpr =
1916 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1917 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1918 const MCSymbolRefExpr *LoExpr =
1919 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1920 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1922 // If it's a 64-bit architecture, expand to:
1923 // la d,sym => lui d,highest(sym)
1924 // ori d,d,higher(sym)
1926 // ori d,d,hi16(sym)
1928 // ori d,d,lo16(sym)
1929 const MCSymbolRefExpr *HighestExpr =
1930 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1931 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1932 const MCSymbolRefExpr *HigherExpr =
1933 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1934 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1936 tmpInst.setOpcode(Mips::LUi);
1937 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1938 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1939 Instructions.push_back(tmpInst);
1941 createLShiftOri<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1943 createLShiftOri<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1945 createLShiftOri<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1948 // Otherwise, expand to:
1949 // la d,sym => lui d,hi16(sym)
1950 // ori d,d,lo16(sym)
1951 tmpInst.setOpcode(Mips::LUi);
1952 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1953 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1954 Instructions.push_back(tmpInst);
1956 createLShiftOri<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1961 bool MipsAsmParser::expandUncondBranchMMPseudo(
1962 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1963 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1964 "unexpected number of operands");
1966 MCOperand Offset = Inst.getOperand(0);
1967 if (Offset.isExpr()) {
1969 Inst.setOpcode(Mips::BEQ_MM);
1970 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1971 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1972 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1974 assert(Offset.isImm() && "expected immediate operand kind");
1975 if (isIntN(11, Offset.getImm())) {
1976 // If offset fits into 11 bits then this instruction becomes microMIPS
1977 // 16-bit unconditional branch instruction.
1978 Inst.setOpcode(Mips::B16_MM);
1980 if (!isIntN(17, Offset.getImm()))
1981 Error(IDLoc, "branch target out of range");
1982 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1983 Error(IDLoc, "branch to misaligned address");
1985 Inst.setOpcode(Mips::BEQ_MM);
1986 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1987 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1988 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1991 Instructions.push_back(Inst);
1993 // If .set reorder is active, emit a NOP after the branch instruction.
1994 if (AssemblerOptions.back()->isReorder())
1995 createNop(true, IDLoc, Instructions);
2000 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2001 SmallVectorImpl<MCInst> &Instructions,
2002 bool isLoad, bool isImmOpnd) {
2003 const MCSymbolRefExpr *SR;
2005 unsigned ImmOffset, HiOffset, LoOffset;
2006 const MCExpr *ExprOffset;
2008 // 1st operand is either the source or destination register.
2009 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2010 unsigned RegOpNum = Inst.getOperand(0).getReg();
2011 // 2nd operand is the base register.
2012 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2013 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2014 // 3rd operand is either an immediate or expression.
2016 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2017 ImmOffset = Inst.getOperand(2).getImm();
2018 LoOffset = ImmOffset & 0x0000ffff;
2019 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2020 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2021 if (LoOffset & 0x8000)
2024 ExprOffset = Inst.getOperand(2).getExpr();
2025 // All instructions will have the same location.
2026 TempInst.setLoc(IDLoc);
2027 // These are some of the types of expansions we perform here:
2028 // 1) lw $8, sym => lui $8, %hi(sym)
2029 // lw $8, %lo(sym)($8)
2030 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2032 // lw $8, %lo(offset)($9)
2033 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2035 // lw $8, %lo(offset)($at)
2036 // 4) sw $8, sym => lui $at, %hi(sym)
2037 // sw $8, %lo(sym)($at)
2038 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2040 // sw $8, %lo(offset)($at)
2041 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2042 // ldc1 $f0, %lo(sym)($at)
2044 // For load instructions we can use the destination register as a temporary
2045 // if base and dst are different (examples 1 and 2) and if the base register
2046 // is general purpose otherwise we must use $at (example 6) and error if it's
2047 // not available. For stores we must use $at (examples 4 and 5) because we
2048 // must not clobber the source register setting up the offset.
2049 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2050 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2051 unsigned RegClassIDOp0 =
2052 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2053 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2054 (RegClassIDOp0 == Mips::GPR64RegClassID);
2055 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2056 TmpRegNum = RegOpNum;
2058 // At this point we need AT to perform the expansions and we exit if it is
2060 TmpRegNum = getATReg(IDLoc);
2065 TempInst.setOpcode(Mips::LUi);
2066 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2068 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2070 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2071 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2072 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2073 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2075 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2077 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2078 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2081 // Add the instruction to the list.
2082 Instructions.push_back(TempInst);
2083 // Prepare TempInst for next instruction.
2085 // Add temp register to base.
2086 if (BaseRegNum != Mips::ZERO) {
2087 TempInst.setOpcode(Mips::ADDu);
2088 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2089 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2090 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2091 Instructions.push_back(TempInst);
2094 // And finally, create original instruction with low part
2095 // of offset and new base.
2096 TempInst.setOpcode(Inst.getOpcode());
2097 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2098 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2100 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2102 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2103 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2104 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2106 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2108 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2109 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2112 Instructions.push_back(TempInst);
2117 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2118 SmallVectorImpl<MCInst> &Instructions) {
2119 unsigned OpNum = Inst.getNumOperands();
2120 unsigned Opcode = Inst.getOpcode();
2121 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2123 assert (Inst.getOperand(OpNum - 1).isImm() &&
2124 Inst.getOperand(OpNum - 2).isReg() &&
2125 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2127 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2128 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2129 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2130 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2131 // It can be implemented as SWM16 or LWM16 instruction.
2132 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2134 Inst.setOpcode(NewOpcode);
2135 Instructions.push_back(Inst);
2139 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2140 SmallVectorImpl<MCInst> &Instructions) {
2142 if (hasShortDelaySlot) {
2143 NopInst.setOpcode(Mips::MOVE16_MM);
2144 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2145 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2147 NopInst.setOpcode(Mips::SLL);
2148 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2149 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2150 NopInst.addOperand(MCOperand::CreateImm(0));
2152 Instructions.push_back(NopInst);
2155 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2156 // As described by the Mips32r2 spec, the registers Rd and Rs for
2157 // jalr.hb must be different.
2158 unsigned Opcode = Inst.getOpcode();
2160 if (Opcode == Mips::JALR_HB &&
2161 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2162 return Match_RequiresDifferentSrcAndDst;
2164 return Match_Success;
2167 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2168 OperandVector &Operands,
2170 uint64_t &ErrorInfo,
2171 bool MatchingInlineAsm) {
2174 SmallVector<MCInst, 8> Instructions;
2175 unsigned MatchResult =
2176 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2178 switch (MatchResult) {
2179 case Match_Success: {
2180 if (processInstruction(Inst, IDLoc, Instructions))
2182 for (unsigned i = 0; i < Instructions.size(); i++)
2183 Out.EmitInstruction(Instructions[i], STI);
2186 case Match_MissingFeature:
2187 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2189 case Match_InvalidOperand: {
2190 SMLoc ErrorLoc = IDLoc;
2191 if (ErrorInfo != ~0ULL) {
2192 if (ErrorInfo >= Operands.size())
2193 return Error(IDLoc, "too few operands for instruction");
2195 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2196 if (ErrorLoc == SMLoc())
2200 return Error(ErrorLoc, "invalid operand for instruction");
2202 case Match_MnemonicFail:
2203 return Error(IDLoc, "invalid instruction");
2204 case Match_RequiresDifferentSrcAndDst:
2205 return Error(IDLoc, "source and destination must be different");
2208 llvm_unreachable("Implement any new match types added!");
2211 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2212 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2213 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2214 ") without \".set noat\"");
2218 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2219 SMRange Range, bool ShowColors) {
2220 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2221 Range, SMFixIt(Range, FixMsg),
2225 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2228 CC = StringSwitch<unsigned>(Name)
2264 if (!(isABI_N32() || isABI_N64()))
2267 if (12 <= CC && CC <= 15) {
2268 // Name is one of t4-t7
2269 AsmToken RegTok = getLexer().peekTok();
2270 SMRange RegRange = RegTok.getLocRange();
2272 StringRef FixedName = StringSwitch<StringRef>(Name)
2278 assert(FixedName != "" && "Register name is not one of t4-t7.");
2280 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2281 "Did you mean $" + FixedName + "?", RegRange);
2284 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2285 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2286 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2287 if (8 <= CC && CC <= 11)
2291 CC = StringSwitch<unsigned>(Name)
2303 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2306 CC = StringSwitch<unsigned>(Name)
2307 .Case("hwr_cpunum", 0)
2308 .Case("hwr_synci_step", 1)
2310 .Case("hwr_ccres", 3)
2311 .Case("hwr_ulr", 29)
2317 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2319 if (Name[0] == 'f') {
2320 StringRef NumString = Name.substr(1);
2322 if (NumString.getAsInteger(10, IntVal))
2323 return -1; // This is not an integer.
2324 if (IntVal > 31) // Maximum index for fpu register.
2331 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2333 if (Name.startswith("fcc")) {
2334 StringRef NumString = Name.substr(3);
2336 if (NumString.getAsInteger(10, IntVal))
2337 return -1; // This is not an integer.
2338 if (IntVal > 7) // There are only 8 fcc registers.
2345 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2347 if (Name.startswith("ac")) {
2348 StringRef NumString = Name.substr(2);
2350 if (NumString.getAsInteger(10, IntVal))
2351 return -1; // This is not an integer.
2352 if (IntVal > 3) // There are only 3 acc registers.
2359 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2362 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2371 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2374 CC = StringSwitch<unsigned>(Name)
2377 .Case("msaaccess", 2)
2379 .Case("msamodify", 4)
2380 .Case("msarequest", 5)
2382 .Case("msaunmap", 7)
2388 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2389 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2391 reportParseError(Loc,
2392 "pseudo-instruction requires $at, which is not available");
2395 unsigned AT = getReg(
2396 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2400 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2401 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2404 unsigned MipsAsmParser::getGPR(int RegNo) {
2405 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2409 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2411 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2414 return getReg(RegClass, RegNum);
2417 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2418 MCAsmParser &Parser = getParser();
2419 DEBUG(dbgs() << "parseOperand\n");
2421 // Check if the current operand has a custom associated parser, if so, try to
2422 // custom parse the operand, or fallback to the general approach.
2423 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2424 if (ResTy == MatchOperand_Success)
2426 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2427 // there was a match, but an error occurred, in which case, just return that
2428 // the operand parsing failed.
2429 if (ResTy == MatchOperand_ParseFail)
2432 DEBUG(dbgs() << ".. Generic Parser\n");
2434 switch (getLexer().getKind()) {
2436 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2438 case AsmToken::Dollar: {
2439 // Parse the register.
2440 SMLoc S = Parser.getTok().getLoc();
2442 // Almost all registers have been parsed by custom parsers. There is only
2443 // one exception to this. $zero (and it's alias $0) will reach this point
2444 // for div, divu, and similar instructions because it is not an operand
2445 // to the instruction definition but an explicit register. Special case
2446 // this situation for now.
2447 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2450 // Maybe it is a symbol reference.
2451 StringRef Identifier;
2452 if (Parser.parseIdentifier(Identifier))
2455 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2456 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2457 // Otherwise create a symbol reference.
2459 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2461 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2464 // Else drop to expression parsing.
2465 case AsmToken::LParen:
2466 case AsmToken::Minus:
2467 case AsmToken::Plus:
2468 case AsmToken::Integer:
2469 case AsmToken::Tilde:
2470 case AsmToken::String: {
2471 DEBUG(dbgs() << ".. generic integer\n");
2472 OperandMatchResultTy ResTy = parseImm(Operands);
2473 return ResTy != MatchOperand_Success;
2475 case AsmToken::Percent: {
2476 // It is a symbol reference or constant expression.
2477 const MCExpr *IdVal;
2478 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2479 if (parseRelocOperand(IdVal))
2482 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2484 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2486 } // case AsmToken::Percent
2487 } // switch(getLexer().getKind())
2491 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2492 StringRef RelocStr) {
2494 // Check the type of the expression.
2495 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2496 // It's a constant, evaluate reloc value.
2498 switch (getVariantKind(RelocStr)) {
2499 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2500 // Get the 1st 16-bits.
2501 Val = MCE->getValue() & 0xffff;
2503 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2504 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2505 // 16 bits being negative.
2506 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2508 case MCSymbolRefExpr::VK_Mips_HIGHER:
2509 // Get the 3rd 16-bits.
2510 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2512 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2513 // Get the 4th 16-bits.
2514 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2517 report_fatal_error("unsupported reloc value");
2519 return MCConstantExpr::Create(Val, getContext());
2522 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2523 // It's a symbol, create a symbolic expression from the symbol.
2524 StringRef Symbol = MSRE->getSymbol().getName();
2525 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2526 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2530 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2531 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2533 // Try to create target expression.
2534 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2535 return MipsMCExpr::Create(VK, Expr, getContext());
2537 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2538 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2539 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2543 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2544 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2545 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2548 // Just return the original expression.
2552 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2554 switch (Expr->getKind()) {
2555 case MCExpr::Constant:
2557 case MCExpr::SymbolRef:
2558 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2559 case MCExpr::Binary:
2560 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2561 if (!isEvaluated(BE->getLHS()))
2563 return isEvaluated(BE->getRHS());
2566 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2567 case MCExpr::Target:
2573 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2574 MCAsmParser &Parser = getParser();
2575 Parser.Lex(); // Eat the % token.
2576 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2577 if (Tok.isNot(AsmToken::Identifier))
2580 std::string Str = Tok.getIdentifier();
2582 Parser.Lex(); // Eat the identifier.
2583 // Now make an expression from the rest of the operand.
2584 const MCExpr *IdVal;
2587 if (getLexer().getKind() == AsmToken::LParen) {
2589 Parser.Lex(); // Eat the '(' token.
2590 if (getLexer().getKind() == AsmToken::Percent) {
2591 Parser.Lex(); // Eat the % token.
2592 const AsmToken &nextTok = Parser.getTok();
2593 if (nextTok.isNot(AsmToken::Identifier))
2596 Str += nextTok.getIdentifier();
2597 Parser.Lex(); // Eat the identifier.
2598 if (getLexer().getKind() != AsmToken::LParen)
2603 if (getParser().parseParenExpression(IdVal, EndLoc))
2606 while (getLexer().getKind() == AsmToken::RParen)
2607 Parser.Lex(); // Eat the ')' token.
2610 return true; // Parenthesis must follow the relocation operand.
2612 Res = evaluateRelocExpr(IdVal, Str);
2616 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2618 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2619 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2620 if (ResTy == MatchOperand_Success) {
2621 assert(Operands.size() == 1);
2622 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2623 StartLoc = Operand.getStartLoc();
2624 EndLoc = Operand.getEndLoc();
2626 // AFAIK, we only support numeric registers and named GPR's in CFI
2628 // Don't worry about eating tokens before failing. Using an unrecognised
2629 // register is a parse error.
2630 if (Operand.isGPRAsmReg()) {
2631 // Resolve to GPR32 or GPR64 appropriately.
2632 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2635 return (RegNo == (unsigned)-1);
2638 assert(Operands.size() == 0);
2639 return (RegNo == (unsigned)-1);
2642 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2643 MCAsmParser &Parser = getParser();
2647 while (getLexer().getKind() == AsmToken::LParen)
2650 switch (getLexer().getKind()) {
2653 case AsmToken::Identifier:
2654 case AsmToken::LParen:
2655 case AsmToken::Integer:
2656 case AsmToken::Minus:
2657 case AsmToken::Plus:
2659 Result = getParser().parseParenExpression(Res, S);
2661 Result = (getParser().parseExpression(Res));
2662 while (getLexer().getKind() == AsmToken::RParen)
2665 case AsmToken::Percent:
2666 Result = parseRelocOperand(Res);
2671 MipsAsmParser::OperandMatchResultTy
2672 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2673 MCAsmParser &Parser = getParser();
2674 DEBUG(dbgs() << "parseMemOperand\n");
2675 const MCExpr *IdVal = nullptr;
2677 bool isParenExpr = false;
2678 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2679 // First operand is the offset.
2680 S = Parser.getTok().getLoc();
2682 if (getLexer().getKind() == AsmToken::LParen) {
2687 if (getLexer().getKind() != AsmToken::Dollar) {
2688 if (parseMemOffset(IdVal, isParenExpr))
2689 return MatchOperand_ParseFail;
2691 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2692 if (Tok.isNot(AsmToken::LParen)) {
2693 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2694 if (Mnemonic.getToken() == "la") {
2696 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2697 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2698 return MatchOperand_Success;
2700 if (Tok.is(AsmToken::EndOfStatement)) {
2702 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2704 // Zero register assumed, add a memory operand with ZERO as its base.
2705 // "Base" will be managed by k_Memory.
2706 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2709 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2710 return MatchOperand_Success;
2712 Error(Parser.getTok().getLoc(), "'(' expected");
2713 return MatchOperand_ParseFail;
2716 Parser.Lex(); // Eat the '(' token.
2719 Res = parseAnyRegister(Operands);
2720 if (Res != MatchOperand_Success)
2723 if (Parser.getTok().isNot(AsmToken::RParen)) {
2724 Error(Parser.getTok().getLoc(), "')' expected");
2725 return MatchOperand_ParseFail;
2728 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2730 Parser.Lex(); // Eat the ')' token.
2733 IdVal = MCConstantExpr::Create(0, getContext());
2735 // Replace the register operand with the memory operand.
2736 std::unique_ptr<MipsOperand> op(
2737 static_cast<MipsOperand *>(Operands.back().release()));
2738 // Remove the register from the operands.
2739 // "op" will be managed by k_Memory.
2740 Operands.pop_back();
2741 // Add the memory operand.
2742 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2744 if (IdVal->EvaluateAsAbsolute(Imm))
2745 IdVal = MCConstantExpr::Create(Imm, getContext());
2746 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2747 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2751 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2752 return MatchOperand_Success;
2755 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2756 MCAsmParser &Parser = getParser();
2757 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2759 SMLoc S = Parser.getTok().getLoc();
2761 if (Sym->isVariable())
2762 Expr = Sym->getVariableValue();
2765 if (Expr->getKind() == MCExpr::SymbolRef) {
2766 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2767 StringRef DefSymbol = Ref->getSymbol().getName();
2768 if (DefSymbol.startswith("$")) {
2769 OperandMatchResultTy ResTy =
2770 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2771 if (ResTy == MatchOperand_Success) {
2774 } else if (ResTy == MatchOperand_ParseFail)
2775 llvm_unreachable("Should never ParseFail");
2778 } else if (Expr->getKind() == MCExpr::Constant) {
2780 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2782 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2789 MipsAsmParser::OperandMatchResultTy
2790 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2791 StringRef Identifier,
2793 int Index = matchCPURegisterName(Identifier);
2795 Operands.push_back(MipsOperand::createGPRReg(
2796 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2797 return MatchOperand_Success;
2800 Index = matchHWRegsRegisterName(Identifier);
2802 Operands.push_back(MipsOperand::createHWRegsReg(
2803 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2804 return MatchOperand_Success;
2807 Index = matchFPURegisterName(Identifier);
2809 Operands.push_back(MipsOperand::createFGRReg(
2810 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2811 return MatchOperand_Success;
2814 Index = matchFCCRegisterName(Identifier);
2816 Operands.push_back(MipsOperand::createFCCReg(
2817 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2818 return MatchOperand_Success;
2821 Index = matchACRegisterName(Identifier);
2823 Operands.push_back(MipsOperand::createACCReg(
2824 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2825 return MatchOperand_Success;
2828 Index = matchMSA128RegisterName(Identifier);
2830 Operands.push_back(MipsOperand::createMSA128Reg(
2831 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2832 return MatchOperand_Success;
2835 Index = matchMSA128CtrlRegisterName(Identifier);
2837 Operands.push_back(MipsOperand::createMSACtrlReg(
2838 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2839 return MatchOperand_Success;
2842 return MatchOperand_NoMatch;
2845 MipsAsmParser::OperandMatchResultTy
2846 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2847 MCAsmParser &Parser = getParser();
2848 auto Token = Parser.getLexer().peekTok(false);
2850 if (Token.is(AsmToken::Identifier)) {
2851 DEBUG(dbgs() << ".. identifier\n");
2852 StringRef Identifier = Token.getIdentifier();
2853 OperandMatchResultTy ResTy =
2854 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2856 } else if (Token.is(AsmToken::Integer)) {
2857 DEBUG(dbgs() << ".. integer\n");
2858 Operands.push_back(MipsOperand::createNumericReg(
2859 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2861 return MatchOperand_Success;
2864 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2866 return MatchOperand_NoMatch;
2869 MipsAsmParser::OperandMatchResultTy
2870 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2871 MCAsmParser &Parser = getParser();
2872 DEBUG(dbgs() << "parseAnyRegister\n");
2874 auto Token = Parser.getTok();
2876 SMLoc S = Token.getLoc();
2878 if (Token.isNot(AsmToken::Dollar)) {
2879 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2880 if (Token.is(AsmToken::Identifier)) {
2881 if (searchSymbolAlias(Operands))
2882 return MatchOperand_Success;
2884 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2885 return MatchOperand_NoMatch;
2887 DEBUG(dbgs() << ".. $\n");
2889 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2890 if (ResTy == MatchOperand_Success) {
2892 Parser.Lex(); // identifier
2897 MipsAsmParser::OperandMatchResultTy
2898 MipsAsmParser::parseImm(OperandVector &Operands) {
2899 MCAsmParser &Parser = getParser();
2900 switch (getLexer().getKind()) {
2902 return MatchOperand_NoMatch;
2903 case AsmToken::LParen:
2904 case AsmToken::Minus:
2905 case AsmToken::Plus:
2906 case AsmToken::Integer:
2907 case AsmToken::Tilde:
2908 case AsmToken::String:
2912 const MCExpr *IdVal;
2913 SMLoc S = Parser.getTok().getLoc();
2914 if (getParser().parseExpression(IdVal))
2915 return MatchOperand_ParseFail;
2917 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2918 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2919 return MatchOperand_Success;
2922 MipsAsmParser::OperandMatchResultTy
2923 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2924 MCAsmParser &Parser = getParser();
2925 DEBUG(dbgs() << "parseJumpTarget\n");
2927 SMLoc S = getLexer().getLoc();
2929 // Integers and expressions are acceptable
2930 OperandMatchResultTy ResTy = parseImm(Operands);
2931 if (ResTy != MatchOperand_NoMatch)
2934 // Registers are a valid target and have priority over symbols.
2935 ResTy = parseAnyRegister(Operands);
2936 if (ResTy != MatchOperand_NoMatch)
2939 const MCExpr *Expr = nullptr;
2940 if (Parser.parseExpression(Expr)) {
2941 // We have no way of knowing if a symbol was consumed so we must ParseFail
2942 return MatchOperand_ParseFail;
2945 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2946 return MatchOperand_Success;
2949 MipsAsmParser::OperandMatchResultTy
2950 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2951 MCAsmParser &Parser = getParser();
2952 const MCExpr *IdVal;
2953 // If the first token is '$' we may have register operand.
2954 if (Parser.getTok().is(AsmToken::Dollar))
2955 return MatchOperand_NoMatch;
2956 SMLoc S = Parser.getTok().getLoc();
2957 if (getParser().parseExpression(IdVal))
2958 return MatchOperand_ParseFail;
2959 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2960 assert(MCE && "Unexpected MCExpr type.");
2961 int64_t Val = MCE->getValue();
2962 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2963 Operands.push_back(MipsOperand::CreateImm(
2964 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2965 return MatchOperand_Success;
2968 MipsAsmParser::OperandMatchResultTy
2969 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2970 MCAsmParser &Parser = getParser();
2971 switch (getLexer().getKind()) {
2973 return MatchOperand_NoMatch;
2974 case AsmToken::LParen:
2975 case AsmToken::Plus:
2976 case AsmToken::Minus:
2977 case AsmToken::Integer:
2982 SMLoc S = Parser.getTok().getLoc();
2984 if (getParser().parseExpression(Expr))
2985 return MatchOperand_ParseFail;
2988 if (!Expr->EvaluateAsAbsolute(Val)) {
2989 Error(S, "expected immediate value");
2990 return MatchOperand_ParseFail;
2993 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2994 // and because the CPU always adds one to the immediate field, the allowed
2995 // range becomes 1..4. We'll only check the range here and will deal
2996 // with the addition/subtraction when actually decoding/encoding
2998 if (Val < 1 || Val > 4) {
2999 Error(S, "immediate not in range (1..4)");
3000 return MatchOperand_ParseFail;
3004 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3005 return MatchOperand_Success;
3008 MipsAsmParser::OperandMatchResultTy
3009 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3010 MCAsmParser &Parser = getParser();
3011 SmallVector<unsigned, 10> Regs;
3013 unsigned PrevReg = Mips::NoRegister;
3014 bool RegRange = false;
3015 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3017 if (Parser.getTok().isNot(AsmToken::Dollar))
3018 return MatchOperand_ParseFail;
3020 SMLoc S = Parser.getTok().getLoc();
3021 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3022 SMLoc E = getLexer().getLoc();
3023 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3024 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3026 // Remove last register operand because registers from register range
3027 // should be inserted first.
3028 if (RegNo == Mips::RA) {
3029 Regs.push_back(RegNo);
3031 unsigned TmpReg = PrevReg + 1;
3032 while (TmpReg <= RegNo) {
3033 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3034 Error(E, "invalid register operand");
3035 return MatchOperand_ParseFail;
3039 Regs.push_back(TmpReg++);
3045 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3046 (RegNo != Mips::RA)) {
3047 Error(E, "$16 or $31 expected");
3048 return MatchOperand_ParseFail;
3049 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3050 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3051 Error(E, "invalid register operand");
3052 return MatchOperand_ParseFail;
3053 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3054 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3055 Error(E, "consecutive register numbers expected");
3056 return MatchOperand_ParseFail;
3059 Regs.push_back(RegNo);
3062 if (Parser.getTok().is(AsmToken::Minus))
3065 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3066 !Parser.getTok().isNot(AsmToken::Comma)) {
3067 Error(E, "',' or '-' expected");
3068 return MatchOperand_ParseFail;
3071 Lex(); // Consume comma or minus
3072 if (Parser.getTok().isNot(AsmToken::Dollar))
3078 SMLoc E = Parser.getTok().getLoc();
3079 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3080 parseMemOperand(Operands);
3081 return MatchOperand_Success;
3084 MipsAsmParser::OperandMatchResultTy
3085 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3086 MCAsmParser &Parser = getParser();
3088 SMLoc S = Parser.getTok().getLoc();
3089 if (parseAnyRegister(Operands) != MatchOperand_Success)
3090 return MatchOperand_ParseFail;
3092 SMLoc E = Parser.getTok().getLoc();
3093 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3094 unsigned Reg = Op.getGPR32Reg();
3095 Operands.pop_back();
3096 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3097 return MatchOperand_Success;
3100 MipsAsmParser::OperandMatchResultTy
3101 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3102 MCAsmParser &Parser = getParser();
3103 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3104 SmallVector<unsigned, 10> Regs;
3106 if (Parser.getTok().isNot(AsmToken::Dollar))
3107 return MatchOperand_ParseFail;
3109 SMLoc S = Parser.getTok().getLoc();
3111 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3112 return MatchOperand_ParseFail;
3114 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3115 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3116 Regs.push_back(RegNo);
3118 SMLoc E = Parser.getTok().getLoc();
3119 if (Parser.getTok().isNot(AsmToken::Comma)) {
3120 Error(E, "',' expected");
3121 return MatchOperand_ParseFail;
3127 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3128 return MatchOperand_ParseFail;
3130 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3131 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3132 Regs.push_back(RegNo);
3134 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3136 return MatchOperand_Success;
3139 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3141 MCSymbolRefExpr::VariantKind VK =
3142 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3143 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3144 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3145 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3146 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3147 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3148 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3149 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3150 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3151 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3152 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3153 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3154 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3155 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3156 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3157 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3158 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3159 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3160 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3161 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3162 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3163 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3164 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3165 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3166 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3167 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3168 .Default(MCSymbolRefExpr::VK_None);
3170 assert(VK != MCSymbolRefExpr::VK_None);
3175 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3177 /// ::= '(', register, ')'
3178 /// handle it before we iterate so we don't get tripped up by the lack of
3180 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3181 MCAsmParser &Parser = getParser();
3182 if (getLexer().is(AsmToken::LParen)) {
3184 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3186 if (parseOperand(Operands, Name)) {
3187 SMLoc Loc = getLexer().getLoc();
3188 Parser.eatToEndOfStatement();
3189 return Error(Loc, "unexpected token in argument list");
3191 if (Parser.getTok().isNot(AsmToken::RParen)) {
3192 SMLoc Loc = getLexer().getLoc();
3193 Parser.eatToEndOfStatement();
3194 return Error(Loc, "unexpected token, expected ')'");
3197 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3203 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3204 /// either one of these.
3205 /// ::= '[', register, ']'
3206 /// ::= '[', integer, ']'
3207 /// handle it before we iterate so we don't get tripped up by the lack of
3209 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3210 OperandVector &Operands) {
3211 MCAsmParser &Parser = getParser();
3212 if (getLexer().is(AsmToken::LBrac)) {
3214 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3216 if (parseOperand(Operands, Name)) {
3217 SMLoc Loc = getLexer().getLoc();
3218 Parser.eatToEndOfStatement();
3219 return Error(Loc, "unexpected token in argument list");
3221 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3222 SMLoc Loc = getLexer().getLoc();
3223 Parser.eatToEndOfStatement();
3224 return Error(Loc, "unexpected token, expected ']'");
3227 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3233 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3234 SMLoc NameLoc, OperandVector &Operands) {
3235 MCAsmParser &Parser = getParser();
3236 DEBUG(dbgs() << "ParseInstruction\n");
3238 // We have reached first instruction, module directive are now forbidden.
3239 getTargetStreamer().forbidModuleDirective();
3241 // Check if we have valid mnemonic
3242 if (!mnemonicIsValid(Name, 0)) {
3243 Parser.eatToEndOfStatement();
3244 return Error(NameLoc, "unknown instruction");
3246 // First operand in MCInst is instruction mnemonic.
3247 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3249 // Read the remaining operands.
3250 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3251 // Read the first operand.
3252 if (parseOperand(Operands, Name)) {
3253 SMLoc Loc = getLexer().getLoc();
3254 Parser.eatToEndOfStatement();
3255 return Error(Loc, "unexpected token in argument list");
3257 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3259 // AFAIK, parenthesis suffixes are never on the first operand
3261 while (getLexer().is(AsmToken::Comma)) {
3262 Parser.Lex(); // Eat the comma.
3263 // Parse and remember the operand.
3264 if (parseOperand(Operands, Name)) {
3265 SMLoc Loc = getLexer().getLoc();
3266 Parser.eatToEndOfStatement();
3267 return Error(Loc, "unexpected token in argument list");
3269 // Parse bracket and parenthesis suffixes before we iterate
3270 if (getLexer().is(AsmToken::LBrac)) {
3271 if (parseBracketSuffix(Name, Operands))
3273 } else if (getLexer().is(AsmToken::LParen) &&
3274 parseParenSuffix(Name, Operands))
3278 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3279 SMLoc Loc = getLexer().getLoc();
3280 Parser.eatToEndOfStatement();
3281 return Error(Loc, "unexpected token in argument list");
3283 Parser.Lex(); // Consume the EndOfStatement.
3287 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3288 MCAsmParser &Parser = getParser();
3289 SMLoc Loc = getLexer().getLoc();
3290 Parser.eatToEndOfStatement();
3291 return Error(Loc, ErrorMsg);
3294 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3295 return Error(Loc, ErrorMsg);
3298 bool MipsAsmParser::parseSetNoAtDirective() {
3299 MCAsmParser &Parser = getParser();
3300 // Line should look like: ".set noat".
3302 // Set the $at register to $0.
3303 AssemblerOptions.back()->setATRegIndex(0);
3305 Parser.Lex(); // Eat "noat".
3307 // If this is not the end of the statement, report an error.
3308 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3309 reportParseError("unexpected token, expected end of statement");
3313 getTargetStreamer().emitDirectiveSetNoAt();
3314 Parser.Lex(); // Consume the EndOfStatement.
3318 bool MipsAsmParser::parseSetAtDirective() {
3319 // Line can be: ".set at", which sets $at to $1
3320 // or ".set at=$reg", which sets $at to $reg.
3321 MCAsmParser &Parser = getParser();
3322 Parser.Lex(); // Eat "at".
3324 if (getLexer().is(AsmToken::EndOfStatement)) {
3325 // No register was specified, so we set $at to $1.
3326 AssemblerOptions.back()->setATRegIndex(1);
3328 getTargetStreamer().emitDirectiveSetAt();
3329 Parser.Lex(); // Consume the EndOfStatement.
3333 if (getLexer().isNot(AsmToken::Equal)) {
3334 reportParseError("unexpected token, expected equals sign");
3337 Parser.Lex(); // Eat "=".
3339 if (getLexer().isNot(AsmToken::Dollar)) {
3340 if (getLexer().is(AsmToken::EndOfStatement)) {
3341 reportParseError("no register specified");
3344 reportParseError("unexpected token, expected dollar sign '$'");
3348 Parser.Lex(); // Eat "$".
3350 // Find out what "reg" is.
3352 const AsmToken &Reg = Parser.getTok();
3353 if (Reg.is(AsmToken::Identifier)) {
3354 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3355 } else if (Reg.is(AsmToken::Integer)) {
3356 AtRegNo = Reg.getIntVal();
3358 reportParseError("unexpected token, expected identifier or integer");
3362 // Check if $reg is a valid register. If it is, set $at to $reg.
3363 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3364 reportParseError("invalid register");
3367 Parser.Lex(); // Eat "reg".
3369 // If this is not the end of the statement, report an error.
3370 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3371 reportParseError("unexpected token, expected end of statement");
3375 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3377 Parser.Lex(); // Consume the EndOfStatement.
3381 bool MipsAsmParser::parseSetReorderDirective() {
3382 MCAsmParser &Parser = getParser();
3384 // If this is not the end of the statement, report an error.
3385 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3386 reportParseError("unexpected token, expected end of statement");
3389 AssemblerOptions.back()->setReorder();
3390 getTargetStreamer().emitDirectiveSetReorder();
3391 Parser.Lex(); // Consume the EndOfStatement.
3395 bool MipsAsmParser::parseSetNoReorderDirective() {
3396 MCAsmParser &Parser = getParser();
3398 // If this is not the end of the statement, report an error.
3399 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3400 reportParseError("unexpected token, expected end of statement");
3403 AssemblerOptions.back()->setNoReorder();
3404 getTargetStreamer().emitDirectiveSetNoReorder();
3405 Parser.Lex(); // Consume the EndOfStatement.
3409 bool MipsAsmParser::parseSetMacroDirective() {
3410 MCAsmParser &Parser = getParser();
3412 // If this is not the end of the statement, report an error.
3413 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3414 reportParseError("unexpected token, expected end of statement");
3417 AssemblerOptions.back()->setMacro();
3418 Parser.Lex(); // Consume the EndOfStatement.
3422 bool MipsAsmParser::parseSetNoMacroDirective() {
3423 MCAsmParser &Parser = getParser();
3425 // If this is not the end of the statement, report an error.
3426 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3427 reportParseError("unexpected token, expected end of statement");
3430 if (AssemblerOptions.back()->isReorder()) {
3431 reportParseError("`noreorder' must be set before `nomacro'");
3434 AssemblerOptions.back()->setNoMacro();
3435 Parser.Lex(); // Consume the EndOfStatement.
3439 bool MipsAsmParser::parseSetMsaDirective() {
3440 MCAsmParser &Parser = getParser();
3443 // If this is not the end of the statement, report an error.
3444 if (getLexer().isNot(AsmToken::EndOfStatement))
3445 return reportParseError("unexpected token, expected end of statement");
3447 setFeatureBits(Mips::FeatureMSA, "msa");
3448 getTargetStreamer().emitDirectiveSetMsa();
3452 bool MipsAsmParser::parseSetNoMsaDirective() {
3453 MCAsmParser &Parser = getParser();
3456 // If this is not the end of the statement, report an error.
3457 if (getLexer().isNot(AsmToken::EndOfStatement))
3458 return reportParseError("unexpected token, expected end of statement");
3460 clearFeatureBits(Mips::FeatureMSA, "msa");
3461 getTargetStreamer().emitDirectiveSetNoMsa();
3465 bool MipsAsmParser::parseSetNoDspDirective() {
3466 MCAsmParser &Parser = getParser();
3467 Parser.Lex(); // Eat "nodsp".
3469 // If this is not the end of the statement, report an error.
3470 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3471 reportParseError("unexpected token, expected end of statement");
3475 clearFeatureBits(Mips::FeatureDSP, "dsp");
3476 getTargetStreamer().emitDirectiveSetNoDsp();
3480 bool MipsAsmParser::parseSetMips16Directive() {
3481 MCAsmParser &Parser = getParser();
3482 Parser.Lex(); // Eat "mips16".
3484 // If this is not the end of the statement, report an error.
3485 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3486 reportParseError("unexpected token, expected end of statement");
3490 setFeatureBits(Mips::FeatureMips16, "mips16");
3491 getTargetStreamer().emitDirectiveSetMips16();
3492 Parser.Lex(); // Consume the EndOfStatement.
3496 bool MipsAsmParser::parseSetNoMips16Directive() {
3497 MCAsmParser &Parser = getParser();
3498 Parser.Lex(); // Eat "nomips16".
3500 // If this is not the end of the statement, report an error.
3501 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3502 reportParseError("unexpected token, expected end of statement");
3506 clearFeatureBits(Mips::FeatureMips16, "mips16");
3507 getTargetStreamer().emitDirectiveSetNoMips16();
3508 Parser.Lex(); // Consume the EndOfStatement.
3512 bool MipsAsmParser::parseSetFpDirective() {
3513 MCAsmParser &Parser = getParser();
3514 MipsABIFlagsSection::FpABIKind FpAbiVal;
3515 // Line can be: .set fp=32
3518 Parser.Lex(); // Eat fp token
3519 AsmToken Tok = Parser.getTok();
3520 if (Tok.isNot(AsmToken::Equal)) {
3521 reportParseError("unexpected token, expected equals sign '='");
3524 Parser.Lex(); // Eat '=' token.
3525 Tok = Parser.getTok();
3527 if (!parseFpABIValue(FpAbiVal, ".set"))
3530 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3531 reportParseError("unexpected token, expected end of statement");
3534 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3535 Parser.Lex(); // Consume the EndOfStatement.
3539 bool MipsAsmParser::parseSetPopDirective() {
3540 MCAsmParser &Parser = getParser();
3541 SMLoc Loc = getLexer().getLoc();
3544 if (getLexer().isNot(AsmToken::EndOfStatement))
3545 return reportParseError("unexpected token, expected end of statement");
3547 // Always keep an element on the options "stack" to prevent the user
3548 // from changing the initial options. This is how we remember them.
3549 if (AssemblerOptions.size() == 2)
3550 return reportParseError(Loc, ".set pop with no .set push");
3552 AssemblerOptions.pop_back();
3553 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3555 getTargetStreamer().emitDirectiveSetPop();
3559 bool MipsAsmParser::parseSetPushDirective() {
3560 MCAsmParser &Parser = getParser();
3562 if (getLexer().isNot(AsmToken::EndOfStatement))
3563 return reportParseError("unexpected token, expected end of statement");
3565 // Create a copy of the current assembler options environment and push it.
3566 AssemblerOptions.push_back(
3567 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3569 getTargetStreamer().emitDirectiveSetPush();
3573 bool MipsAsmParser::parseSetAssignment() {
3575 const MCExpr *Value;
3576 MCAsmParser &Parser = getParser();
3578 if (Parser.parseIdentifier(Name))
3579 reportParseError("expected identifier after .set");
3581 if (getLexer().isNot(AsmToken::Comma))
3582 return reportParseError("unexpected token, expected comma");
3585 if (Parser.parseExpression(Value))
3586 return reportParseError("expected valid expression after comma");
3588 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3589 Sym->setVariableValue(Value);
3594 bool MipsAsmParser::parseSetMips0Directive() {
3595 MCAsmParser &Parser = getParser();
3597 if (getLexer().isNot(AsmToken::EndOfStatement))
3598 return reportParseError("unexpected token, expected end of statement");
3600 // Reset assembler options to their initial values.
3601 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3602 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3604 getTargetStreamer().emitDirectiveSetMips0();
3608 bool MipsAsmParser::parseSetArchDirective() {
3609 MCAsmParser &Parser = getParser();
3611 if (getLexer().isNot(AsmToken::Equal))
3612 return reportParseError("unexpected token, expected equals sign");
3616 if (Parser.parseIdentifier(Arch))
3617 return reportParseError("expected arch identifier");
3619 StringRef ArchFeatureName =
3620 StringSwitch<StringRef>(Arch)
3621 .Case("mips1", "mips1")
3622 .Case("mips2", "mips2")
3623 .Case("mips3", "mips3")
3624 .Case("mips4", "mips4")
3625 .Case("mips5", "mips5")
3626 .Case("mips32", "mips32")
3627 .Case("mips32r2", "mips32r2")
3628 .Case("mips32r3", "mips32r3")
3629 .Case("mips32r5", "mips32r5")
3630 .Case("mips32r6", "mips32r6")
3631 .Case("mips64", "mips64")
3632 .Case("mips64r2", "mips64r2")
3633 .Case("mips64r3", "mips64r3")
3634 .Case("mips64r5", "mips64r5")
3635 .Case("mips64r6", "mips64r6")
3636 .Case("cnmips", "cnmips")
3637 .Case("r4000", "mips3") // This is an implementation of Mips3.
3640 if (ArchFeatureName.empty())
3641 return reportParseError("unsupported architecture");
3643 selectArch(ArchFeatureName);
3644 getTargetStreamer().emitDirectiveSetArch(Arch);
3648 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3649 MCAsmParser &Parser = getParser();
3651 if (getLexer().isNot(AsmToken::EndOfStatement))
3652 return reportParseError("unexpected token, expected end of statement");
3656 llvm_unreachable("Unimplemented feature");
3657 case Mips::FeatureDSP:
3658 setFeatureBits(Mips::FeatureDSP, "dsp");
3659 getTargetStreamer().emitDirectiveSetDsp();
3661 case Mips::FeatureMicroMips:
3662 getTargetStreamer().emitDirectiveSetMicroMips();
3664 case Mips::FeatureMips1:
3665 selectArch("mips1");
3666 getTargetStreamer().emitDirectiveSetMips1();
3668 case Mips::FeatureMips2:
3669 selectArch("mips2");
3670 getTargetStreamer().emitDirectiveSetMips2();
3672 case Mips::FeatureMips3:
3673 selectArch("mips3");
3674 getTargetStreamer().emitDirectiveSetMips3();
3676 case Mips::FeatureMips4:
3677 selectArch("mips4");
3678 getTargetStreamer().emitDirectiveSetMips4();
3680 case Mips::FeatureMips5:
3681 selectArch("mips5");
3682 getTargetStreamer().emitDirectiveSetMips5();
3684 case Mips::FeatureMips32:
3685 selectArch("mips32");
3686 getTargetStreamer().emitDirectiveSetMips32();
3688 case Mips::FeatureMips32r2:
3689 selectArch("mips32r2");
3690 getTargetStreamer().emitDirectiveSetMips32R2();
3692 case Mips::FeatureMips32r3:
3693 selectArch("mips32r3");
3694 getTargetStreamer().emitDirectiveSetMips32R3();
3696 case Mips::FeatureMips32r5:
3697 selectArch("mips32r5");
3698 getTargetStreamer().emitDirectiveSetMips32R5();
3700 case Mips::FeatureMips32r6:
3701 selectArch("mips32r6");
3702 getTargetStreamer().emitDirectiveSetMips32R6();
3704 case Mips::FeatureMips64:
3705 selectArch("mips64");
3706 getTargetStreamer().emitDirectiveSetMips64();
3708 case Mips::FeatureMips64r2:
3709 selectArch("mips64r2");
3710 getTargetStreamer().emitDirectiveSetMips64R2();
3712 case Mips::FeatureMips64r3:
3713 selectArch("mips64r3");
3714 getTargetStreamer().emitDirectiveSetMips64R3();
3716 case Mips::FeatureMips64r5:
3717 selectArch("mips64r5");
3718 getTargetStreamer().emitDirectiveSetMips64R5();
3720 case Mips::FeatureMips64r6:
3721 selectArch("mips64r6");
3722 getTargetStreamer().emitDirectiveSetMips64R6();
3728 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3729 MCAsmParser &Parser = getParser();
3730 if (getLexer().isNot(AsmToken::Comma)) {
3731 SMLoc Loc = getLexer().getLoc();
3732 Parser.eatToEndOfStatement();
3733 return Error(Loc, ErrorStr);
3736 Parser.Lex(); // Eat the comma.
3740 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3741 if (AssemblerOptions.back()->isReorder())
3742 Warning(Loc, ".cpload should be inside a noreorder section");
3744 if (inMips16Mode()) {
3745 reportParseError(".cpload is not supported in Mips16 mode");
3749 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3750 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3751 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3752 reportParseError("expected register containing function address");
3756 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3757 if (!RegOpnd.isGPRAsmReg()) {
3758 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3762 // If this is not the end of the statement, report an error.
3763 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3764 reportParseError("unexpected token, expected end of statement");
3768 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3772 bool MipsAsmParser::parseDirectiveCPSetup() {
3773 MCAsmParser &Parser = getParser();
3776 bool SaveIsReg = true;
3778 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3779 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3780 if (ResTy == MatchOperand_NoMatch) {
3781 reportParseError("expected register containing function address");
3782 Parser.eatToEndOfStatement();
3786 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3787 if (!FuncRegOpnd.isGPRAsmReg()) {
3788 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3789 Parser.eatToEndOfStatement();
3793 FuncReg = FuncRegOpnd.getGPR32Reg();
3796 if (!eatComma("unexpected token, expected comma"))
3799 ResTy = parseAnyRegister(TmpReg);
3800 if (ResTy == MatchOperand_NoMatch) {
3801 const AsmToken &Tok = Parser.getTok();
3802 if (Tok.is(AsmToken::Integer)) {
3803 Save = Tok.getIntVal();
3807 reportParseError("expected save register or stack offset");
3808 Parser.eatToEndOfStatement();
3812 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3813 if (!SaveOpnd.isGPRAsmReg()) {
3814 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3815 Parser.eatToEndOfStatement();
3818 Save = SaveOpnd.getGPR32Reg();
3821 if (!eatComma("unexpected token, expected comma"))
3825 if (Parser.parseExpression(Expr)) {
3826 reportParseError("expected expression");
3830 if (Expr->getKind() != MCExpr::SymbolRef) {
3831 reportParseError("expected symbol");
3834 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3836 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3841 bool MipsAsmParser::parseDirectiveNaN() {
3842 MCAsmParser &Parser = getParser();
3843 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3844 const AsmToken &Tok = Parser.getTok();
3846 if (Tok.getString() == "2008") {
3848 getTargetStreamer().emitDirectiveNaN2008();
3850 } else if (Tok.getString() == "legacy") {
3852 getTargetStreamer().emitDirectiveNaNLegacy();
3856 // If we don't recognize the option passed to the .nan
3857 // directive (e.g. no option or unknown option), emit an error.
3858 reportParseError("invalid option in .nan directive");
3862 bool MipsAsmParser::parseDirectiveSet() {
3863 MCAsmParser &Parser = getParser();
3864 // Get the next token.
3865 const AsmToken &Tok = Parser.getTok();
3867 if (Tok.getString() == "noat") {
3868 return parseSetNoAtDirective();
3869 } else if (Tok.getString() == "at") {
3870 return parseSetAtDirective();
3871 } else if (Tok.getString() == "arch") {
3872 return parseSetArchDirective();
3873 } else if (Tok.getString() == "fp") {
3874 return parseSetFpDirective();
3875 } else if (Tok.getString() == "pop") {
3876 return parseSetPopDirective();
3877 } else if (Tok.getString() == "push") {
3878 return parseSetPushDirective();
3879 } else if (Tok.getString() == "reorder") {
3880 return parseSetReorderDirective();
3881 } else if (Tok.getString() == "noreorder") {
3882 return parseSetNoReorderDirective();
3883 } else if (Tok.getString() == "macro") {
3884 return parseSetMacroDirective();
3885 } else if (Tok.getString() == "nomacro") {
3886 return parseSetNoMacroDirective();
3887 } else if (Tok.getString() == "mips16") {
3888 return parseSetMips16Directive();
3889 } else if (Tok.getString() == "nomips16") {
3890 return parseSetNoMips16Directive();
3891 } else if (Tok.getString() == "nomicromips") {
3892 getTargetStreamer().emitDirectiveSetNoMicroMips();
3893 Parser.eatToEndOfStatement();
3895 } else if (Tok.getString() == "micromips") {
3896 return parseSetFeature(Mips::FeatureMicroMips);
3897 } else if (Tok.getString() == "mips0") {
3898 return parseSetMips0Directive();
3899 } else if (Tok.getString() == "mips1") {
3900 return parseSetFeature(Mips::FeatureMips1);
3901 } else if (Tok.getString() == "mips2") {
3902 return parseSetFeature(Mips::FeatureMips2);
3903 } else if (Tok.getString() == "mips3") {
3904 return parseSetFeature(Mips::FeatureMips3);
3905 } else if (Tok.getString() == "mips4") {
3906 return parseSetFeature(Mips::FeatureMips4);
3907 } else if (Tok.getString() == "mips5") {
3908 return parseSetFeature(Mips::FeatureMips5);
3909 } else if (Tok.getString() == "mips32") {
3910 return parseSetFeature(Mips::FeatureMips32);
3911 } else if (Tok.getString() == "mips32r2") {
3912 return parseSetFeature(Mips::FeatureMips32r2);
3913 } else if (Tok.getString() == "mips32r3") {
3914 return parseSetFeature(Mips::FeatureMips32r3);
3915 } else if (Tok.getString() == "mips32r5") {
3916 return parseSetFeature(Mips::FeatureMips32r5);
3917 } else if (Tok.getString() == "mips32r6") {
3918 return parseSetFeature(Mips::FeatureMips32r6);
3919 } else if (Tok.getString() == "mips64") {
3920 return parseSetFeature(Mips::FeatureMips64);
3921 } else if (Tok.getString() == "mips64r2") {
3922 return parseSetFeature(Mips::FeatureMips64r2);
3923 } else if (Tok.getString() == "mips64r3") {
3924 return parseSetFeature(Mips::FeatureMips64r3);
3925 } else if (Tok.getString() == "mips64r5") {
3926 return parseSetFeature(Mips::FeatureMips64r5);
3927 } else if (Tok.getString() == "mips64r6") {
3928 return parseSetFeature(Mips::FeatureMips64r6);
3929 } else if (Tok.getString() == "dsp") {
3930 return parseSetFeature(Mips::FeatureDSP);
3931 } else if (Tok.getString() == "nodsp") {
3932 return parseSetNoDspDirective();
3933 } else if (Tok.getString() == "msa") {
3934 return parseSetMsaDirective();
3935 } else if (Tok.getString() == "nomsa") {
3936 return parseSetNoMsaDirective();
3938 // It is just an identifier, look for an assignment.
3939 parseSetAssignment();
3946 /// parseDataDirective
3947 /// ::= .word [ expression (, expression)* ]
3948 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3949 MCAsmParser &Parser = getParser();
3950 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3952 const MCExpr *Value;
3953 if (getParser().parseExpression(Value))
3956 getParser().getStreamer().EmitValue(Value, Size);
3958 if (getLexer().is(AsmToken::EndOfStatement))
3961 if (getLexer().isNot(AsmToken::Comma))
3962 return Error(L, "unexpected token, expected comma");
3971 /// parseDirectiveGpWord
3972 /// ::= .gpword local_sym
3973 bool MipsAsmParser::parseDirectiveGpWord() {
3974 MCAsmParser &Parser = getParser();
3975 const MCExpr *Value;
3976 // EmitGPRel32Value requires an expression, so we are using base class
3977 // method to evaluate the expression.
3978 if (getParser().parseExpression(Value))
3980 getParser().getStreamer().EmitGPRel32Value(Value);
3982 if (getLexer().isNot(AsmToken::EndOfStatement))
3983 return Error(getLexer().getLoc(),
3984 "unexpected token, expected end of statement");
3985 Parser.Lex(); // Eat EndOfStatement token.
3989 /// parseDirectiveGpDWord
3990 /// ::= .gpdword local_sym
3991 bool MipsAsmParser::parseDirectiveGpDWord() {
3992 MCAsmParser &Parser = getParser();
3993 const MCExpr *Value;
3994 // EmitGPRel64Value requires an expression, so we are using base class
3995 // method to evaluate the expression.
3996 if (getParser().parseExpression(Value))
3998 getParser().getStreamer().EmitGPRel64Value(Value);
4000 if (getLexer().isNot(AsmToken::EndOfStatement))
4001 return Error(getLexer().getLoc(),
4002 "unexpected token, expected end of statement");
4003 Parser.Lex(); // Eat EndOfStatement token.
4007 bool MipsAsmParser::parseDirectiveOption() {
4008 MCAsmParser &Parser = getParser();
4009 // Get the option token.
4010 AsmToken Tok = Parser.getTok();
4011 // At the moment only identifiers are supported.
4012 if (Tok.isNot(AsmToken::Identifier)) {
4013 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4014 Parser.eatToEndOfStatement();
4018 StringRef Option = Tok.getIdentifier();
4020 if (Option == "pic0") {
4021 getTargetStreamer().emitDirectiveOptionPic0();
4023 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4024 Error(Parser.getTok().getLoc(),
4025 "unexpected token, expected end of statement");
4026 Parser.eatToEndOfStatement();
4031 if (Option == "pic2") {
4032 getTargetStreamer().emitDirectiveOptionPic2();
4034 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4035 Error(Parser.getTok().getLoc(),
4036 "unexpected token, expected end of statement");
4037 Parser.eatToEndOfStatement();
4043 Warning(Parser.getTok().getLoc(),
4044 "unknown option, expected 'pic0' or 'pic2'");
4045 Parser.eatToEndOfStatement();
4049 /// parseInsnDirective
4051 bool MipsAsmParser::parseInsnDirective() {
4052 // If this is not the end of the statement, report an error.
4053 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4054 reportParseError("unexpected token, expected end of statement");
4058 // The actual label marking happens in
4059 // MipsELFStreamer::createPendingLabelRelocs().
4060 getTargetStreamer().emitDirectiveInsn();
4062 getParser().Lex(); // Eat EndOfStatement token.
4066 /// parseDirectiveModule
4067 /// ::= .module oddspreg
4068 /// ::= .module nooddspreg
4069 /// ::= .module fp=value
4070 bool MipsAsmParser::parseDirectiveModule() {
4071 MCAsmParser &Parser = getParser();
4072 MCAsmLexer &Lexer = getLexer();
4073 SMLoc L = Lexer.getLoc();
4075 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4076 // TODO : get a better message.
4077 reportParseError(".module directive must appear before any code");
4082 if (Parser.parseIdentifier(Option)) {
4083 reportParseError("expected .module option identifier");
4087 if (Option == "oddspreg") {
4088 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4089 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4091 // If this is not the end of the statement, report an error.
4092 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4093 reportParseError("unexpected token, expected end of statement");
4097 return false; // parseDirectiveModule has finished successfully.
4098 } else if (Option == "nooddspreg") {
4100 Error(L, "'.module nooddspreg' requires the O32 ABI");
4104 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4105 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4107 // If this is not the end of the statement, report an error.
4108 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4109 reportParseError("unexpected token, expected end of statement");
4113 return false; // parseDirectiveModule has finished successfully.
4114 } else if (Option == "fp") {
4115 return parseDirectiveModuleFP();
4117 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4121 /// parseDirectiveModuleFP
4125 bool MipsAsmParser::parseDirectiveModuleFP() {
4126 MCAsmParser &Parser = getParser();
4127 MCAsmLexer &Lexer = getLexer();
4129 if (Lexer.isNot(AsmToken::Equal)) {
4130 reportParseError("unexpected token, expected equals sign '='");
4133 Parser.Lex(); // Eat '=' token.
4135 MipsABIFlagsSection::FpABIKind FpABI;
4136 if (!parseFpABIValue(FpABI, ".module"))
4139 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4140 reportParseError("unexpected token, expected end of statement");
4144 // Emit appropriate flags.
4145 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4146 Parser.Lex(); // Consume the EndOfStatement.
4150 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4151 StringRef Directive) {
4152 MCAsmParser &Parser = getParser();
4153 MCAsmLexer &Lexer = getLexer();
4155 if (Lexer.is(AsmToken::Identifier)) {
4156 StringRef Value = Parser.getTok().getString();
4159 if (Value != "xx") {
4160 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4165 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4169 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4173 if (Lexer.is(AsmToken::Integer)) {
4174 unsigned Value = Parser.getTok().getIntVal();
4177 if (Value != 32 && Value != 64) {
4178 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4184 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4188 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4190 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4198 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4199 MCAsmParser &Parser = getParser();
4200 StringRef IDVal = DirectiveID.getString();
4202 if (IDVal == ".cpload")
4203 return parseDirectiveCpLoad(DirectiveID.getLoc());
4204 if (IDVal == ".dword") {
4205 parseDataDirective(8, DirectiveID.getLoc());
4208 if (IDVal == ".ent") {
4209 StringRef SymbolName;
4211 if (Parser.parseIdentifier(SymbolName)) {
4212 reportParseError("expected identifier after .ent");
4216 // There's an undocumented extension that allows an integer to
4217 // follow the name of the procedure which AFAICS is ignored by GAS.
4218 // Example: .ent foo,2
4219 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4220 if (getLexer().isNot(AsmToken::Comma)) {
4221 // Even though we accept this undocumented extension for compatibility
4222 // reasons, the additional integer argument does not actually change
4223 // the behaviour of the '.ent' directive, so we would like to discourage
4224 // its use. We do this by not referring to the extended version in
4225 // error messages which are not directly related to its use.
4226 reportParseError("unexpected token, expected end of statement");
4229 Parser.Lex(); // Eat the comma.
4230 const MCExpr *DummyNumber;
4231 int64_t DummyNumberVal;
4232 // If the user was explicitly trying to use the extended version,
4233 // we still give helpful extension-related error messages.
4234 if (Parser.parseExpression(DummyNumber)) {
4235 reportParseError("expected number after comma");
4238 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4239 reportParseError("expected an absolute expression after comma");
4244 // If this is not the end of the statement, report an error.
4245 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4246 reportParseError("unexpected token, expected end of statement");
4250 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4252 getTargetStreamer().emitDirectiveEnt(*Sym);
4257 if (IDVal == ".end") {
4258 StringRef SymbolName;
4260 if (Parser.parseIdentifier(SymbolName)) {
4261 reportParseError("expected identifier after .end");
4265 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4266 reportParseError("unexpected token, expected end of statement");
4270 if (CurrentFn == nullptr) {
4271 reportParseError(".end used without .ent");
4275 if ((SymbolName != CurrentFn->getName())) {
4276 reportParseError(".end symbol does not match .ent symbol");
4280 getTargetStreamer().emitDirectiveEnd(SymbolName);
4281 CurrentFn = nullptr;
4285 if (IDVal == ".frame") {
4286 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4287 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4288 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4289 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4290 reportParseError("expected stack register");
4294 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4295 if (!StackRegOpnd.isGPRAsmReg()) {
4296 reportParseError(StackRegOpnd.getStartLoc(),
4297 "expected general purpose register");
4300 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4302 if (Parser.getTok().is(AsmToken::Comma))
4305 reportParseError("unexpected token, expected comma");
4309 // Parse the frame size.
4310 const MCExpr *FrameSize;
4311 int64_t FrameSizeVal;
4313 if (Parser.parseExpression(FrameSize)) {
4314 reportParseError("expected frame size value");
4318 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4319 reportParseError("frame size not an absolute expression");
4323 if (Parser.getTok().is(AsmToken::Comma))
4326 reportParseError("unexpected token, expected comma");
4330 // Parse the return register.
4332 ResTy = parseAnyRegister(TmpReg);
4333 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4334 reportParseError("expected return register");
4338 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4339 if (!ReturnRegOpnd.isGPRAsmReg()) {
4340 reportParseError(ReturnRegOpnd.getStartLoc(),
4341 "expected general purpose register");
4345 // If this is not the end of the statement, report an error.
4346 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4347 reportParseError("unexpected token, expected end of statement");
4351 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4352 ReturnRegOpnd.getGPR32Reg());
4356 if (IDVal == ".set") {
4357 return parseDirectiveSet();
4360 if (IDVal == ".mask" || IDVal == ".fmask") {
4361 // .mask bitmask, frame_offset
4362 // bitmask: One bit for each register used.
4363 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4364 // first register is expected to be saved.
4366 // .mask 0x80000000, -4
4367 // .fmask 0x80000000, -4
4370 // Parse the bitmask
4371 const MCExpr *BitMask;
4374 if (Parser.parseExpression(BitMask)) {
4375 reportParseError("expected bitmask value");
4379 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4380 reportParseError("bitmask not an absolute expression");
4384 if (Parser.getTok().is(AsmToken::Comma))
4387 reportParseError("unexpected token, expected comma");
4391 // Parse the frame_offset
4392 const MCExpr *FrameOffset;
4393 int64_t FrameOffsetVal;
4395 if (Parser.parseExpression(FrameOffset)) {
4396 reportParseError("expected frame offset value");
4400 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4401 reportParseError("frame offset not an absolute expression");
4405 // If this is not the end of the statement, report an error.
4406 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4407 reportParseError("unexpected token, expected end of statement");
4411 if (IDVal == ".mask")
4412 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4414 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4418 if (IDVal == ".nan")
4419 return parseDirectiveNaN();
4421 if (IDVal == ".gpword") {
4422 parseDirectiveGpWord();
4426 if (IDVal == ".gpdword") {
4427 parseDirectiveGpDWord();
4431 if (IDVal == ".word") {
4432 parseDataDirective(4, DirectiveID.getLoc());
4436 if (IDVal == ".option")
4437 return parseDirectiveOption();
4439 if (IDVal == ".abicalls") {
4440 getTargetStreamer().emitDirectiveAbiCalls();
4441 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4442 Error(Parser.getTok().getLoc(),
4443 "unexpected token, expected end of statement");
4445 Parser.eatToEndOfStatement();
4450 if (IDVal == ".cpsetup")
4451 return parseDirectiveCPSetup();
4453 if (IDVal == ".module")
4454 return parseDirectiveModule();
4456 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4457 return parseInternalDirectiveReallowModule();
4459 if (IDVal == ".insn")
4460 return parseInsnDirective();
4465 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4466 // If this is not the end of the statement, report an error.
4467 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4468 reportParseError("unexpected token, expected end of statement");
4472 getTargetStreamer().reallowModuleDirective();
4474 getParser().Lex(); // Eat EndOfStatement token.
4478 extern "C" void LLVMInitializeMipsAsmParser() {
4479 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4480 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4481 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4482 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4485 #define GET_REGISTER_MATCHER
4486 #define GET_MATCHER_IMPLEMENTATION
4487 #include "MipsGenAsmMatcher.inc"