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 tmpInst.setOpcode(Mips::ORi);
1649 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1650 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1651 tmpInst.addOperand(Operand);
1652 tmpInst.setLoc(IDLoc);
1653 Instructions.push_back(tmpInst);
1656 template <int Shift, bool PerformShift>
1657 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1658 SmallVectorImpl<MCInst> &Instructions) {
1659 createLShiftOri<PerformShift>(
1660 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1661 IDLoc, Instructions);
1665 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1666 SmallVectorImpl<MCInst> &Instructions) {
1667 // Create a JALR instruction which is going to replace the pseudo-JAL.
1669 JalrInst.setLoc(IDLoc);
1670 const MCOperand FirstRegOp = Inst.getOperand(0);
1671 const unsigned Opcode = Inst.getOpcode();
1673 if (Opcode == Mips::JalOneReg) {
1674 // jal $rs => jalr $rs
1675 if (inMicroMipsMode()) {
1676 JalrInst.setOpcode(Mips::JALR16_MM);
1677 JalrInst.addOperand(FirstRegOp);
1679 JalrInst.setOpcode(Mips::JALR);
1680 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1681 JalrInst.addOperand(FirstRegOp);
1683 } else if (Opcode == Mips::JalTwoReg) {
1684 // jal $rd, $rs => jalr $rd, $rs
1685 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1686 JalrInst.addOperand(FirstRegOp);
1687 const MCOperand SecondRegOp = Inst.getOperand(1);
1688 JalrInst.addOperand(SecondRegOp);
1690 Instructions.push_back(JalrInst);
1692 // If .set reorder is active, emit a NOP after it.
1693 if (AssemblerOptions.back()->isReorder()) {
1694 // This is a 32-bit NOP because these 2 pseudo-instructions
1695 // do not have a short delay slot.
1697 NopInst.setOpcode(Mips::SLL);
1698 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1699 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1700 NopInst.addOperand(MCOperand::CreateImm(0));
1701 Instructions.push_back(NopInst);
1707 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1708 SmallVectorImpl<MCInst> &Instructions) {
1710 const MCOperand &ImmOp = Inst.getOperand(1);
1711 assert(ImmOp.isImm() && "expected immediate operand kind");
1712 const MCOperand &RegOp = Inst.getOperand(0);
1713 assert(RegOp.isReg() && "expected register operand kind");
1715 int64_t ImmValue = ImmOp.getImm();
1716 unsigned Reg = RegOp.getReg();
1717 tmpInst.setLoc(IDLoc);
1718 // FIXME: gas has a special case for values that are 000...1111, which
1719 // becomes a li -1 and then a dsrl
1720 if (0 <= ImmValue && ImmValue <= 65535) {
1721 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1722 // li d,j => ori d,$zero,j
1723 tmpInst.setOpcode(Mips::ORi);
1724 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1725 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1726 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1727 Instructions.push_back(tmpInst);
1728 } else if (ImmValue < 0 && ImmValue >= -32768) {
1729 // For negative signed 16-bit values (-32768 <= j < 0):
1730 // li d,j => addiu d,$zero,j
1731 tmpInst.setOpcode(Mips::ADDiu);
1732 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1733 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1734 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1735 Instructions.push_back(tmpInst);
1736 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1737 // For all other values which are representable as a 32-bit integer:
1738 // li d,j => lui d,hi16(j)
1740 tmpInst.setOpcode(Mips::LUi);
1741 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1742 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1743 Instructions.push_back(tmpInst);
1744 createLShiftOri<0, false>(ImmValue, Reg, IDLoc, Instructions);
1745 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1747 Error(IDLoc, "instruction requires a 64-bit architecture");
1751 // <------- lo32 ------>
1752 // <------- hi32 ------>
1753 // <- hi16 -> <- lo16 ->
1754 // _________________________________
1756 // | 16-bits | 16-bits | 16-bits |
1757 // |__________|__________|__________|
1759 // For any 64-bit value that is representable as a 48-bit integer:
1760 // li d,j => lui d,hi16(j)
1761 // ori d,d,hi16(lo32(j))
1763 // ori d,d,lo16(lo32(j))
1764 tmpInst.setOpcode(Mips::LUi);
1765 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1767 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1768 Instructions.push_back(tmpInst);
1769 createLShiftOri<16, false>(ImmValue, Reg, IDLoc, Instructions);
1770 createLShiftOri<0, true>(ImmValue, Reg, IDLoc, Instructions);
1773 Error(IDLoc, "instruction requires a 64-bit architecture");
1777 // <------- hi32 ------> <------- lo32 ------>
1778 // <- hi16 -> <- lo16 ->
1779 // ___________________________________________
1781 // | 16-bits | 16-bits | 16-bits | 16-bits |
1782 // |__________|__________|__________|__________|
1784 // For all other values which are representable as a 64-bit integer:
1785 // li d,j => lui d,hi16(j)
1786 // ori d,d,lo16(hi32(j))
1788 // ori d,d,hi16(lo32(j))
1790 // ori d,d,lo16(lo32(j))
1791 tmpInst.setOpcode(Mips::LUi);
1792 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1794 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1795 Instructions.push_back(tmpInst);
1796 createLShiftOri<32, false>(ImmValue, Reg, IDLoc, Instructions);
1797 createLShiftOri<16, true>(ImmValue, Reg, IDLoc, Instructions);
1798 createLShiftOri<0, true>(ImmValue, Reg, IDLoc, Instructions);
1804 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1805 SmallVectorImpl<MCInst> &Instructions) {
1807 const MCOperand &ImmOp = Inst.getOperand(2);
1808 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1809 "expected immediate operand kind");
1810 if (!ImmOp.isImm()) {
1811 expandLoadAddressSym(Inst, IDLoc, Instructions);
1814 const MCOperand &SrcRegOp = Inst.getOperand(1);
1815 assert(SrcRegOp.isReg() && "expected register operand kind");
1816 const MCOperand &DstRegOp = Inst.getOperand(0);
1817 assert(DstRegOp.isReg() && "expected register operand kind");
1818 int ImmValue = ImmOp.getImm();
1819 if (-32768 <= ImmValue && ImmValue <= 65535) {
1820 // For -32768 <= j <= 65535.
1821 // la d,j(s) => addiu d,s,j
1822 tmpInst.setOpcode(Mips::ADDiu);
1823 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1824 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1825 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1826 Instructions.push_back(tmpInst);
1828 // For any other value of j that is representable as a 32-bit integer.
1829 // la d,j(s) => lui d,hi16(j)
1832 tmpInst.setOpcode(Mips::LUi);
1833 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1834 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1835 Instructions.push_back(tmpInst);
1837 tmpInst.setOpcode(Mips::ORi);
1838 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1839 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1840 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1841 Instructions.push_back(tmpInst);
1843 tmpInst.setOpcode(Mips::ADDu);
1844 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1845 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1846 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1847 Instructions.push_back(tmpInst);
1853 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1854 SmallVectorImpl<MCInst> &Instructions) {
1856 const MCOperand &ImmOp = Inst.getOperand(1);
1857 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1858 "expected immediate operand kind");
1859 if (!ImmOp.isImm()) {
1860 expandLoadAddressSym(Inst, IDLoc, Instructions);
1863 const MCOperand &RegOp = Inst.getOperand(0);
1864 assert(RegOp.isReg() && "expected register operand kind");
1865 int ImmValue = ImmOp.getImm();
1866 if (-32768 <= ImmValue && ImmValue <= 65535) {
1867 // For -32768 <= j <= 65535.
1868 // la d,j => addiu d,$zero,j
1869 tmpInst.setOpcode(Mips::ADDiu);
1870 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1871 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1872 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1873 Instructions.push_back(tmpInst);
1875 // For any other value of j that is representable as a 32-bit integer.
1876 // la d,j => lui d,hi16(j)
1878 tmpInst.setOpcode(Mips::LUi);
1879 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1880 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1881 Instructions.push_back(tmpInst);
1883 tmpInst.setOpcode(Mips::ORi);
1884 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1885 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1886 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1887 Instructions.push_back(tmpInst);
1893 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1894 SmallVectorImpl<MCInst> &Instructions) {
1895 // FIXME: If we do have a valid at register to use, we should generate a
1896 // slightly shorter sequence here.
1898 int ExprOperandNo = 1;
1899 // Sometimes the assembly parser will get the immediate expression as
1900 // a $zero + an immediate.
1901 if (Inst.getNumOperands() == 3) {
1902 assert(Inst.getOperand(1).getReg() ==
1903 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1906 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1907 assert(SymOp.isExpr() && "expected symbol operand kind");
1908 const MCOperand &RegOp = Inst.getOperand(0);
1909 unsigned RegNo = RegOp.getReg();
1910 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1911 const MCSymbolRefExpr *HiExpr =
1912 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1913 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1914 const MCSymbolRefExpr *LoExpr =
1915 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1916 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1918 // If it's a 64-bit architecture, expand to:
1919 // la d,sym => lui d,highest(sym)
1920 // ori d,d,higher(sym)
1922 // ori d,d,hi16(sym)
1924 // ori d,d,lo16(sym)
1925 const MCSymbolRefExpr *HighestExpr =
1926 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1927 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1928 const MCSymbolRefExpr *HigherExpr =
1929 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1930 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1932 tmpInst.setOpcode(Mips::LUi);
1933 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1934 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1935 Instructions.push_back(tmpInst);
1937 createLShiftOri<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1939 createLShiftOri<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1941 createLShiftOri<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1944 // Otherwise, expand to:
1945 // la d,sym => lui d,hi16(sym)
1946 // ori d,d,lo16(sym)
1947 tmpInst.setOpcode(Mips::LUi);
1948 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1949 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1950 Instructions.push_back(tmpInst);
1952 createLShiftOri<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1957 bool MipsAsmParser::expandUncondBranchMMPseudo(
1958 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1959 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1960 "unexpected number of operands");
1962 MCOperand Offset = Inst.getOperand(0);
1963 if (Offset.isExpr()) {
1965 Inst.setOpcode(Mips::BEQ_MM);
1966 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1967 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1968 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1970 assert(Offset.isImm() && "expected immediate operand kind");
1971 if (isIntN(11, Offset.getImm())) {
1972 // If offset fits into 11 bits then this instruction becomes microMIPS
1973 // 16-bit unconditional branch instruction.
1974 Inst.setOpcode(Mips::B16_MM);
1976 if (!isIntN(17, Offset.getImm()))
1977 Error(IDLoc, "branch target out of range");
1978 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1979 Error(IDLoc, "branch to misaligned address");
1981 Inst.setOpcode(Mips::BEQ_MM);
1982 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1983 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1984 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1987 Instructions.push_back(Inst);
1989 // If .set reorder is active, emit a NOP after the branch instruction.
1990 if (AssemblerOptions.back()->isReorder())
1991 createNop(true, IDLoc, Instructions);
1996 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1997 SmallVectorImpl<MCInst> &Instructions,
1998 bool isLoad, bool isImmOpnd) {
1999 const MCSymbolRefExpr *SR;
2001 unsigned ImmOffset, HiOffset, LoOffset;
2002 const MCExpr *ExprOffset;
2004 // 1st operand is either the source or destination register.
2005 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2006 unsigned RegOpNum = Inst.getOperand(0).getReg();
2007 // 2nd operand is the base register.
2008 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2009 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2010 // 3rd operand is either an immediate or expression.
2012 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2013 ImmOffset = Inst.getOperand(2).getImm();
2014 LoOffset = ImmOffset & 0x0000ffff;
2015 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2016 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2017 if (LoOffset & 0x8000)
2020 ExprOffset = Inst.getOperand(2).getExpr();
2021 // All instructions will have the same location.
2022 TempInst.setLoc(IDLoc);
2023 // These are some of the types of expansions we perform here:
2024 // 1) lw $8, sym => lui $8, %hi(sym)
2025 // lw $8, %lo(sym)($8)
2026 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2028 // lw $8, %lo(offset)($9)
2029 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2031 // lw $8, %lo(offset)($at)
2032 // 4) sw $8, sym => lui $at, %hi(sym)
2033 // sw $8, %lo(sym)($at)
2034 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2036 // sw $8, %lo(offset)($at)
2037 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2038 // ldc1 $f0, %lo(sym)($at)
2040 // For load instructions we can use the destination register as a temporary
2041 // if base and dst are different (examples 1 and 2) and if the base register
2042 // is general purpose otherwise we must use $at (example 6) and error if it's
2043 // not available. For stores we must use $at (examples 4 and 5) because we
2044 // must not clobber the source register setting up the offset.
2045 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2046 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2047 unsigned RegClassIDOp0 =
2048 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2049 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2050 (RegClassIDOp0 == Mips::GPR64RegClassID);
2051 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2052 TmpRegNum = RegOpNum;
2054 // At this point we need AT to perform the expansions and we exit if it is
2056 TmpRegNum = getATReg(IDLoc);
2061 TempInst.setOpcode(Mips::LUi);
2062 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2064 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2066 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2067 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2068 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2069 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2071 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2073 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2074 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2077 // Add the instruction to the list.
2078 Instructions.push_back(TempInst);
2079 // Prepare TempInst for next instruction.
2081 // Add temp register to base.
2082 if (BaseRegNum != Mips::ZERO) {
2083 TempInst.setOpcode(Mips::ADDu);
2084 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2085 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2086 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2087 Instructions.push_back(TempInst);
2090 // And finally, create original instruction with low part
2091 // of offset and new base.
2092 TempInst.setOpcode(Inst.getOpcode());
2093 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2094 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2096 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2098 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2099 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2100 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2102 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2104 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2105 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2108 Instructions.push_back(TempInst);
2113 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2114 SmallVectorImpl<MCInst> &Instructions) {
2115 unsigned OpNum = Inst.getNumOperands();
2116 unsigned Opcode = Inst.getOpcode();
2117 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2119 assert (Inst.getOperand(OpNum - 1).isImm() &&
2120 Inst.getOperand(OpNum - 2).isReg() &&
2121 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2123 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2124 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2125 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2126 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2127 // It can be implemented as SWM16 or LWM16 instruction.
2128 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2130 Inst.setOpcode(NewOpcode);
2131 Instructions.push_back(Inst);
2135 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2136 SmallVectorImpl<MCInst> &Instructions) {
2138 if (hasShortDelaySlot) {
2139 NopInst.setOpcode(Mips::MOVE16_MM);
2140 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2141 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2143 NopInst.setOpcode(Mips::SLL);
2144 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2145 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2146 NopInst.addOperand(MCOperand::CreateImm(0));
2148 Instructions.push_back(NopInst);
2151 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2152 // As described by the Mips32r2 spec, the registers Rd and Rs for
2153 // jalr.hb must be different.
2154 unsigned Opcode = Inst.getOpcode();
2156 if (Opcode == Mips::JALR_HB &&
2157 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2158 return Match_RequiresDifferentSrcAndDst;
2160 return Match_Success;
2163 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2164 OperandVector &Operands,
2166 uint64_t &ErrorInfo,
2167 bool MatchingInlineAsm) {
2170 SmallVector<MCInst, 8> Instructions;
2171 unsigned MatchResult =
2172 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2174 switch (MatchResult) {
2175 case Match_Success: {
2176 if (processInstruction(Inst, IDLoc, Instructions))
2178 for (unsigned i = 0; i < Instructions.size(); i++)
2179 Out.EmitInstruction(Instructions[i], STI);
2182 case Match_MissingFeature:
2183 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2185 case Match_InvalidOperand: {
2186 SMLoc ErrorLoc = IDLoc;
2187 if (ErrorInfo != ~0ULL) {
2188 if (ErrorInfo >= Operands.size())
2189 return Error(IDLoc, "too few operands for instruction");
2191 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2192 if (ErrorLoc == SMLoc())
2196 return Error(ErrorLoc, "invalid operand for instruction");
2198 case Match_MnemonicFail:
2199 return Error(IDLoc, "invalid instruction");
2200 case Match_RequiresDifferentSrcAndDst:
2201 return Error(IDLoc, "source and destination must be different");
2204 llvm_unreachable("Implement any new match types added!");
2207 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2208 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2209 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2210 ") without \".set noat\"");
2214 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2215 SMRange Range, bool ShowColors) {
2216 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2217 Range, SMFixIt(Range, FixMsg),
2221 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2224 CC = StringSwitch<unsigned>(Name)
2260 if (!(isABI_N32() || isABI_N64()))
2263 if (12 <= CC && CC <= 15) {
2264 // Name is one of t4-t7
2265 AsmToken RegTok = getLexer().peekTok();
2266 SMRange RegRange = RegTok.getLocRange();
2268 StringRef FixedName = StringSwitch<StringRef>(Name)
2274 assert(FixedName != "" && "Register name is not one of t4-t7.");
2276 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2277 "Did you mean $" + FixedName + "?", RegRange);
2280 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2281 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2282 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2283 if (8 <= CC && CC <= 11)
2287 CC = StringSwitch<unsigned>(Name)
2299 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2302 CC = StringSwitch<unsigned>(Name)
2303 .Case("hwr_cpunum", 0)
2304 .Case("hwr_synci_step", 1)
2306 .Case("hwr_ccres", 3)
2307 .Case("hwr_ulr", 29)
2313 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2315 if (Name[0] == 'f') {
2316 StringRef NumString = Name.substr(1);
2318 if (NumString.getAsInteger(10, IntVal))
2319 return -1; // This is not an integer.
2320 if (IntVal > 31) // Maximum index for fpu register.
2327 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2329 if (Name.startswith("fcc")) {
2330 StringRef NumString = Name.substr(3);
2332 if (NumString.getAsInteger(10, IntVal))
2333 return -1; // This is not an integer.
2334 if (IntVal > 7) // There are only 8 fcc registers.
2341 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2343 if (Name.startswith("ac")) {
2344 StringRef NumString = Name.substr(2);
2346 if (NumString.getAsInteger(10, IntVal))
2347 return -1; // This is not an integer.
2348 if (IntVal > 3) // There are only 3 acc registers.
2355 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2358 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2367 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2370 CC = StringSwitch<unsigned>(Name)
2373 .Case("msaaccess", 2)
2375 .Case("msamodify", 4)
2376 .Case("msarequest", 5)
2378 .Case("msaunmap", 7)
2384 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2385 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2387 reportParseError(Loc,
2388 "pseudo-instruction requires $at, which is not available");
2391 unsigned AT = getReg(
2392 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2396 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2397 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2400 unsigned MipsAsmParser::getGPR(int RegNo) {
2401 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2405 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2407 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2410 return getReg(RegClass, RegNum);
2413 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2414 MCAsmParser &Parser = getParser();
2415 DEBUG(dbgs() << "parseOperand\n");
2417 // Check if the current operand has a custom associated parser, if so, try to
2418 // custom parse the operand, or fallback to the general approach.
2419 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2420 if (ResTy == MatchOperand_Success)
2422 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2423 // there was a match, but an error occurred, in which case, just return that
2424 // the operand parsing failed.
2425 if (ResTy == MatchOperand_ParseFail)
2428 DEBUG(dbgs() << ".. Generic Parser\n");
2430 switch (getLexer().getKind()) {
2432 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2434 case AsmToken::Dollar: {
2435 // Parse the register.
2436 SMLoc S = Parser.getTok().getLoc();
2438 // Almost all registers have been parsed by custom parsers. There is only
2439 // one exception to this. $zero (and it's alias $0) will reach this point
2440 // for div, divu, and similar instructions because it is not an operand
2441 // to the instruction definition but an explicit register. Special case
2442 // this situation for now.
2443 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2446 // Maybe it is a symbol reference.
2447 StringRef Identifier;
2448 if (Parser.parseIdentifier(Identifier))
2451 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2452 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2453 // Otherwise create a symbol reference.
2455 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2457 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2460 // Else drop to expression parsing.
2461 case AsmToken::LParen:
2462 case AsmToken::Minus:
2463 case AsmToken::Plus:
2464 case AsmToken::Integer:
2465 case AsmToken::Tilde:
2466 case AsmToken::String: {
2467 DEBUG(dbgs() << ".. generic integer\n");
2468 OperandMatchResultTy ResTy = parseImm(Operands);
2469 return ResTy != MatchOperand_Success;
2471 case AsmToken::Percent: {
2472 // It is a symbol reference or constant expression.
2473 const MCExpr *IdVal;
2474 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2475 if (parseRelocOperand(IdVal))
2478 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2480 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2482 } // case AsmToken::Percent
2483 } // switch(getLexer().getKind())
2487 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2488 StringRef RelocStr) {
2490 // Check the type of the expression.
2491 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2492 // It's a constant, evaluate reloc value.
2494 switch (getVariantKind(RelocStr)) {
2495 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2496 // Get the 1st 16-bits.
2497 Val = MCE->getValue() & 0xffff;
2499 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2500 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2501 // 16 bits being negative.
2502 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2504 case MCSymbolRefExpr::VK_Mips_HIGHER:
2505 // Get the 3rd 16-bits.
2506 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2508 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2509 // Get the 4th 16-bits.
2510 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2513 report_fatal_error("unsupported reloc value");
2515 return MCConstantExpr::Create(Val, getContext());
2518 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2519 // It's a symbol, create a symbolic expression from the symbol.
2520 StringRef Symbol = MSRE->getSymbol().getName();
2521 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2522 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2526 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2527 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2529 // Try to create target expression.
2530 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2531 return MipsMCExpr::Create(VK, Expr, getContext());
2533 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2534 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2535 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2539 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2540 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2541 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2544 // Just return the original expression.
2548 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2550 switch (Expr->getKind()) {
2551 case MCExpr::Constant:
2553 case MCExpr::SymbolRef:
2554 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2555 case MCExpr::Binary:
2556 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2557 if (!isEvaluated(BE->getLHS()))
2559 return isEvaluated(BE->getRHS());
2562 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2563 case MCExpr::Target:
2569 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2570 MCAsmParser &Parser = getParser();
2571 Parser.Lex(); // Eat the % token.
2572 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2573 if (Tok.isNot(AsmToken::Identifier))
2576 std::string Str = Tok.getIdentifier();
2578 Parser.Lex(); // Eat the identifier.
2579 // Now make an expression from the rest of the operand.
2580 const MCExpr *IdVal;
2583 if (getLexer().getKind() == AsmToken::LParen) {
2585 Parser.Lex(); // Eat the '(' token.
2586 if (getLexer().getKind() == AsmToken::Percent) {
2587 Parser.Lex(); // Eat the % token.
2588 const AsmToken &nextTok = Parser.getTok();
2589 if (nextTok.isNot(AsmToken::Identifier))
2592 Str += nextTok.getIdentifier();
2593 Parser.Lex(); // Eat the identifier.
2594 if (getLexer().getKind() != AsmToken::LParen)
2599 if (getParser().parseParenExpression(IdVal, EndLoc))
2602 while (getLexer().getKind() == AsmToken::RParen)
2603 Parser.Lex(); // Eat the ')' token.
2606 return true; // Parenthesis must follow the relocation operand.
2608 Res = evaluateRelocExpr(IdVal, Str);
2612 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2614 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2615 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2616 if (ResTy == MatchOperand_Success) {
2617 assert(Operands.size() == 1);
2618 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2619 StartLoc = Operand.getStartLoc();
2620 EndLoc = Operand.getEndLoc();
2622 // AFAIK, we only support numeric registers and named GPR's in CFI
2624 // Don't worry about eating tokens before failing. Using an unrecognised
2625 // register is a parse error.
2626 if (Operand.isGPRAsmReg()) {
2627 // Resolve to GPR32 or GPR64 appropriately.
2628 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2631 return (RegNo == (unsigned)-1);
2634 assert(Operands.size() == 0);
2635 return (RegNo == (unsigned)-1);
2638 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2639 MCAsmParser &Parser = getParser();
2643 while (getLexer().getKind() == AsmToken::LParen)
2646 switch (getLexer().getKind()) {
2649 case AsmToken::Identifier:
2650 case AsmToken::LParen:
2651 case AsmToken::Integer:
2652 case AsmToken::Minus:
2653 case AsmToken::Plus:
2655 Result = getParser().parseParenExpression(Res, S);
2657 Result = (getParser().parseExpression(Res));
2658 while (getLexer().getKind() == AsmToken::RParen)
2661 case AsmToken::Percent:
2662 Result = parseRelocOperand(Res);
2667 MipsAsmParser::OperandMatchResultTy
2668 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2669 MCAsmParser &Parser = getParser();
2670 DEBUG(dbgs() << "parseMemOperand\n");
2671 const MCExpr *IdVal = nullptr;
2673 bool isParenExpr = false;
2674 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2675 // First operand is the offset.
2676 S = Parser.getTok().getLoc();
2678 if (getLexer().getKind() == AsmToken::LParen) {
2683 if (getLexer().getKind() != AsmToken::Dollar) {
2684 if (parseMemOffset(IdVal, isParenExpr))
2685 return MatchOperand_ParseFail;
2687 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2688 if (Tok.isNot(AsmToken::LParen)) {
2689 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2690 if (Mnemonic.getToken() == "la") {
2692 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2693 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2694 return MatchOperand_Success;
2696 if (Tok.is(AsmToken::EndOfStatement)) {
2698 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2700 // Zero register assumed, add a memory operand with ZERO as its base.
2701 // "Base" will be managed by k_Memory.
2702 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2705 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2706 return MatchOperand_Success;
2708 Error(Parser.getTok().getLoc(), "'(' expected");
2709 return MatchOperand_ParseFail;
2712 Parser.Lex(); // Eat the '(' token.
2715 Res = parseAnyRegister(Operands);
2716 if (Res != MatchOperand_Success)
2719 if (Parser.getTok().isNot(AsmToken::RParen)) {
2720 Error(Parser.getTok().getLoc(), "')' expected");
2721 return MatchOperand_ParseFail;
2724 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2726 Parser.Lex(); // Eat the ')' token.
2729 IdVal = MCConstantExpr::Create(0, getContext());
2731 // Replace the register operand with the memory operand.
2732 std::unique_ptr<MipsOperand> op(
2733 static_cast<MipsOperand *>(Operands.back().release()));
2734 // Remove the register from the operands.
2735 // "op" will be managed by k_Memory.
2736 Operands.pop_back();
2737 // Add the memory operand.
2738 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2740 if (IdVal->EvaluateAsAbsolute(Imm))
2741 IdVal = MCConstantExpr::Create(Imm, getContext());
2742 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2743 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2747 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2748 return MatchOperand_Success;
2751 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2752 MCAsmParser &Parser = getParser();
2753 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2755 SMLoc S = Parser.getTok().getLoc();
2757 if (Sym->isVariable())
2758 Expr = Sym->getVariableValue();
2761 if (Expr->getKind() == MCExpr::SymbolRef) {
2762 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2763 StringRef DefSymbol = Ref->getSymbol().getName();
2764 if (DefSymbol.startswith("$")) {
2765 OperandMatchResultTy ResTy =
2766 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2767 if (ResTy == MatchOperand_Success) {
2770 } else if (ResTy == MatchOperand_ParseFail)
2771 llvm_unreachable("Should never ParseFail");
2774 } else if (Expr->getKind() == MCExpr::Constant) {
2776 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2778 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2785 MipsAsmParser::OperandMatchResultTy
2786 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2787 StringRef Identifier,
2789 int Index = matchCPURegisterName(Identifier);
2791 Operands.push_back(MipsOperand::createGPRReg(
2792 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2793 return MatchOperand_Success;
2796 Index = matchHWRegsRegisterName(Identifier);
2798 Operands.push_back(MipsOperand::createHWRegsReg(
2799 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2800 return MatchOperand_Success;
2803 Index = matchFPURegisterName(Identifier);
2805 Operands.push_back(MipsOperand::createFGRReg(
2806 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2807 return MatchOperand_Success;
2810 Index = matchFCCRegisterName(Identifier);
2812 Operands.push_back(MipsOperand::createFCCReg(
2813 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2814 return MatchOperand_Success;
2817 Index = matchACRegisterName(Identifier);
2819 Operands.push_back(MipsOperand::createACCReg(
2820 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2821 return MatchOperand_Success;
2824 Index = matchMSA128RegisterName(Identifier);
2826 Operands.push_back(MipsOperand::createMSA128Reg(
2827 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2828 return MatchOperand_Success;
2831 Index = matchMSA128CtrlRegisterName(Identifier);
2833 Operands.push_back(MipsOperand::createMSACtrlReg(
2834 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2835 return MatchOperand_Success;
2838 return MatchOperand_NoMatch;
2841 MipsAsmParser::OperandMatchResultTy
2842 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2843 MCAsmParser &Parser = getParser();
2844 auto Token = Parser.getLexer().peekTok(false);
2846 if (Token.is(AsmToken::Identifier)) {
2847 DEBUG(dbgs() << ".. identifier\n");
2848 StringRef Identifier = Token.getIdentifier();
2849 OperandMatchResultTy ResTy =
2850 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2852 } else if (Token.is(AsmToken::Integer)) {
2853 DEBUG(dbgs() << ".. integer\n");
2854 Operands.push_back(MipsOperand::createNumericReg(
2855 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2857 return MatchOperand_Success;
2860 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2862 return MatchOperand_NoMatch;
2865 MipsAsmParser::OperandMatchResultTy
2866 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2867 MCAsmParser &Parser = getParser();
2868 DEBUG(dbgs() << "parseAnyRegister\n");
2870 auto Token = Parser.getTok();
2872 SMLoc S = Token.getLoc();
2874 if (Token.isNot(AsmToken::Dollar)) {
2875 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2876 if (Token.is(AsmToken::Identifier)) {
2877 if (searchSymbolAlias(Operands))
2878 return MatchOperand_Success;
2880 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2881 return MatchOperand_NoMatch;
2883 DEBUG(dbgs() << ".. $\n");
2885 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2886 if (ResTy == MatchOperand_Success) {
2888 Parser.Lex(); // identifier
2893 MipsAsmParser::OperandMatchResultTy
2894 MipsAsmParser::parseImm(OperandVector &Operands) {
2895 MCAsmParser &Parser = getParser();
2896 switch (getLexer().getKind()) {
2898 return MatchOperand_NoMatch;
2899 case AsmToken::LParen:
2900 case AsmToken::Minus:
2901 case AsmToken::Plus:
2902 case AsmToken::Integer:
2903 case AsmToken::Tilde:
2904 case AsmToken::String:
2908 const MCExpr *IdVal;
2909 SMLoc S = Parser.getTok().getLoc();
2910 if (getParser().parseExpression(IdVal))
2911 return MatchOperand_ParseFail;
2913 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2914 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2915 return MatchOperand_Success;
2918 MipsAsmParser::OperandMatchResultTy
2919 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2920 MCAsmParser &Parser = getParser();
2921 DEBUG(dbgs() << "parseJumpTarget\n");
2923 SMLoc S = getLexer().getLoc();
2925 // Integers and expressions are acceptable
2926 OperandMatchResultTy ResTy = parseImm(Operands);
2927 if (ResTy != MatchOperand_NoMatch)
2930 // Registers are a valid target and have priority over symbols.
2931 ResTy = parseAnyRegister(Operands);
2932 if (ResTy != MatchOperand_NoMatch)
2935 const MCExpr *Expr = nullptr;
2936 if (Parser.parseExpression(Expr)) {
2937 // We have no way of knowing if a symbol was consumed so we must ParseFail
2938 return MatchOperand_ParseFail;
2941 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2942 return MatchOperand_Success;
2945 MipsAsmParser::OperandMatchResultTy
2946 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2947 MCAsmParser &Parser = getParser();
2948 const MCExpr *IdVal;
2949 // If the first token is '$' we may have register operand.
2950 if (Parser.getTok().is(AsmToken::Dollar))
2951 return MatchOperand_NoMatch;
2952 SMLoc S = Parser.getTok().getLoc();
2953 if (getParser().parseExpression(IdVal))
2954 return MatchOperand_ParseFail;
2955 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2956 assert(MCE && "Unexpected MCExpr type.");
2957 int64_t Val = MCE->getValue();
2958 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2959 Operands.push_back(MipsOperand::CreateImm(
2960 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2961 return MatchOperand_Success;
2964 MipsAsmParser::OperandMatchResultTy
2965 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2966 MCAsmParser &Parser = getParser();
2967 switch (getLexer().getKind()) {
2969 return MatchOperand_NoMatch;
2970 case AsmToken::LParen:
2971 case AsmToken::Plus:
2972 case AsmToken::Minus:
2973 case AsmToken::Integer:
2978 SMLoc S = Parser.getTok().getLoc();
2980 if (getParser().parseExpression(Expr))
2981 return MatchOperand_ParseFail;
2984 if (!Expr->EvaluateAsAbsolute(Val)) {
2985 Error(S, "expected immediate value");
2986 return MatchOperand_ParseFail;
2989 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2990 // and because the CPU always adds one to the immediate field, the allowed
2991 // range becomes 1..4. We'll only check the range here and will deal
2992 // with the addition/subtraction when actually decoding/encoding
2994 if (Val < 1 || Val > 4) {
2995 Error(S, "immediate not in range (1..4)");
2996 return MatchOperand_ParseFail;
3000 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3001 return MatchOperand_Success;
3004 MipsAsmParser::OperandMatchResultTy
3005 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3006 MCAsmParser &Parser = getParser();
3007 SmallVector<unsigned, 10> Regs;
3009 unsigned PrevReg = Mips::NoRegister;
3010 bool RegRange = false;
3011 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3013 if (Parser.getTok().isNot(AsmToken::Dollar))
3014 return MatchOperand_ParseFail;
3016 SMLoc S = Parser.getTok().getLoc();
3017 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3018 SMLoc E = getLexer().getLoc();
3019 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3020 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3022 // Remove last register operand because registers from register range
3023 // should be inserted first.
3024 if (RegNo == Mips::RA) {
3025 Regs.push_back(RegNo);
3027 unsigned TmpReg = PrevReg + 1;
3028 while (TmpReg <= RegNo) {
3029 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3030 Error(E, "invalid register operand");
3031 return MatchOperand_ParseFail;
3035 Regs.push_back(TmpReg++);
3041 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3042 (RegNo != Mips::RA)) {
3043 Error(E, "$16 or $31 expected");
3044 return MatchOperand_ParseFail;
3045 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3046 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3047 Error(E, "invalid register operand");
3048 return MatchOperand_ParseFail;
3049 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3050 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3051 Error(E, "consecutive register numbers expected");
3052 return MatchOperand_ParseFail;
3055 Regs.push_back(RegNo);
3058 if (Parser.getTok().is(AsmToken::Minus))
3061 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3062 !Parser.getTok().isNot(AsmToken::Comma)) {
3063 Error(E, "',' or '-' expected");
3064 return MatchOperand_ParseFail;
3067 Lex(); // Consume comma or minus
3068 if (Parser.getTok().isNot(AsmToken::Dollar))
3074 SMLoc E = Parser.getTok().getLoc();
3075 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3076 parseMemOperand(Operands);
3077 return MatchOperand_Success;
3080 MipsAsmParser::OperandMatchResultTy
3081 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3082 MCAsmParser &Parser = getParser();
3084 SMLoc S = Parser.getTok().getLoc();
3085 if (parseAnyRegister(Operands) != MatchOperand_Success)
3086 return MatchOperand_ParseFail;
3088 SMLoc E = Parser.getTok().getLoc();
3089 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3090 unsigned Reg = Op.getGPR32Reg();
3091 Operands.pop_back();
3092 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3093 return MatchOperand_Success;
3096 MipsAsmParser::OperandMatchResultTy
3097 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3098 MCAsmParser &Parser = getParser();
3099 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3100 SmallVector<unsigned, 10> Regs;
3102 if (Parser.getTok().isNot(AsmToken::Dollar))
3103 return MatchOperand_ParseFail;
3105 SMLoc S = Parser.getTok().getLoc();
3107 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3108 return MatchOperand_ParseFail;
3110 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3111 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3112 Regs.push_back(RegNo);
3114 SMLoc E = Parser.getTok().getLoc();
3115 if (Parser.getTok().isNot(AsmToken::Comma)) {
3116 Error(E, "',' expected");
3117 return MatchOperand_ParseFail;
3123 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3124 return MatchOperand_ParseFail;
3126 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3127 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3128 Regs.push_back(RegNo);
3130 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3132 return MatchOperand_Success;
3135 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3137 MCSymbolRefExpr::VariantKind VK =
3138 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3139 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3140 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3141 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3142 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3143 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3144 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3145 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3146 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3147 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3148 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3149 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3150 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3151 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3152 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3153 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3154 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3155 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3156 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3157 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3158 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3159 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3160 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3161 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3162 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3163 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3164 .Default(MCSymbolRefExpr::VK_None);
3166 assert(VK != MCSymbolRefExpr::VK_None);
3171 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3173 /// ::= '(', register, ')'
3174 /// handle it before we iterate so we don't get tripped up by the lack of
3176 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3177 MCAsmParser &Parser = getParser();
3178 if (getLexer().is(AsmToken::LParen)) {
3180 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3182 if (parseOperand(Operands, Name)) {
3183 SMLoc Loc = getLexer().getLoc();
3184 Parser.eatToEndOfStatement();
3185 return Error(Loc, "unexpected token in argument list");
3187 if (Parser.getTok().isNot(AsmToken::RParen)) {
3188 SMLoc Loc = getLexer().getLoc();
3189 Parser.eatToEndOfStatement();
3190 return Error(Loc, "unexpected token, expected ')'");
3193 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3199 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3200 /// either one of these.
3201 /// ::= '[', register, ']'
3202 /// ::= '[', integer, ']'
3203 /// handle it before we iterate so we don't get tripped up by the lack of
3205 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3206 OperandVector &Operands) {
3207 MCAsmParser &Parser = getParser();
3208 if (getLexer().is(AsmToken::LBrac)) {
3210 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3212 if (parseOperand(Operands, Name)) {
3213 SMLoc Loc = getLexer().getLoc();
3214 Parser.eatToEndOfStatement();
3215 return Error(Loc, "unexpected token in argument list");
3217 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3218 SMLoc Loc = getLexer().getLoc();
3219 Parser.eatToEndOfStatement();
3220 return Error(Loc, "unexpected token, expected ']'");
3223 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3229 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3230 SMLoc NameLoc, OperandVector &Operands) {
3231 MCAsmParser &Parser = getParser();
3232 DEBUG(dbgs() << "ParseInstruction\n");
3234 // We have reached first instruction, module directive are now forbidden.
3235 getTargetStreamer().forbidModuleDirective();
3237 // Check if we have valid mnemonic
3238 if (!mnemonicIsValid(Name, 0)) {
3239 Parser.eatToEndOfStatement();
3240 return Error(NameLoc, "unknown instruction");
3242 // First operand in MCInst is instruction mnemonic.
3243 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3245 // Read the remaining operands.
3246 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3247 // Read the first operand.
3248 if (parseOperand(Operands, Name)) {
3249 SMLoc Loc = getLexer().getLoc();
3250 Parser.eatToEndOfStatement();
3251 return Error(Loc, "unexpected token in argument list");
3253 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3255 // AFAIK, parenthesis suffixes are never on the first operand
3257 while (getLexer().is(AsmToken::Comma)) {
3258 Parser.Lex(); // Eat the comma.
3259 // Parse and remember the operand.
3260 if (parseOperand(Operands, Name)) {
3261 SMLoc Loc = getLexer().getLoc();
3262 Parser.eatToEndOfStatement();
3263 return Error(Loc, "unexpected token in argument list");
3265 // Parse bracket and parenthesis suffixes before we iterate
3266 if (getLexer().is(AsmToken::LBrac)) {
3267 if (parseBracketSuffix(Name, Operands))
3269 } else if (getLexer().is(AsmToken::LParen) &&
3270 parseParenSuffix(Name, Operands))
3274 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3275 SMLoc Loc = getLexer().getLoc();
3276 Parser.eatToEndOfStatement();
3277 return Error(Loc, "unexpected token in argument list");
3279 Parser.Lex(); // Consume the EndOfStatement.
3283 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3284 MCAsmParser &Parser = getParser();
3285 SMLoc Loc = getLexer().getLoc();
3286 Parser.eatToEndOfStatement();
3287 return Error(Loc, ErrorMsg);
3290 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3291 return Error(Loc, ErrorMsg);
3294 bool MipsAsmParser::parseSetNoAtDirective() {
3295 MCAsmParser &Parser = getParser();
3296 // Line should look like: ".set noat".
3298 // Set the $at register to $0.
3299 AssemblerOptions.back()->setATRegIndex(0);
3301 Parser.Lex(); // Eat "noat".
3303 // If this is not the end of the statement, report an error.
3304 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3305 reportParseError("unexpected token, expected end of statement");
3309 getTargetStreamer().emitDirectiveSetNoAt();
3310 Parser.Lex(); // Consume the EndOfStatement.
3314 bool MipsAsmParser::parseSetAtDirective() {
3315 // Line can be: ".set at", which sets $at to $1
3316 // or ".set at=$reg", which sets $at to $reg.
3317 MCAsmParser &Parser = getParser();
3318 Parser.Lex(); // Eat "at".
3320 if (getLexer().is(AsmToken::EndOfStatement)) {
3321 // No register was specified, so we set $at to $1.
3322 AssemblerOptions.back()->setATRegIndex(1);
3324 getTargetStreamer().emitDirectiveSetAt();
3325 Parser.Lex(); // Consume the EndOfStatement.
3329 if (getLexer().isNot(AsmToken::Equal)) {
3330 reportParseError("unexpected token, expected equals sign");
3333 Parser.Lex(); // Eat "=".
3335 if (getLexer().isNot(AsmToken::Dollar)) {
3336 if (getLexer().is(AsmToken::EndOfStatement)) {
3337 reportParseError("no register specified");
3340 reportParseError("unexpected token, expected dollar sign '$'");
3344 Parser.Lex(); // Eat "$".
3346 // Find out what "reg" is.
3348 const AsmToken &Reg = Parser.getTok();
3349 if (Reg.is(AsmToken::Identifier)) {
3350 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3351 } else if (Reg.is(AsmToken::Integer)) {
3352 AtRegNo = Reg.getIntVal();
3354 reportParseError("unexpected token, expected identifier or integer");
3358 // Check if $reg is a valid register. If it is, set $at to $reg.
3359 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3360 reportParseError("invalid register");
3363 Parser.Lex(); // Eat "reg".
3365 // If this is not the end of the statement, report an error.
3366 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3367 reportParseError("unexpected token, expected end of statement");
3371 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3373 Parser.Lex(); // Consume the EndOfStatement.
3377 bool MipsAsmParser::parseSetReorderDirective() {
3378 MCAsmParser &Parser = getParser();
3380 // If this is not the end of the statement, report an error.
3381 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3382 reportParseError("unexpected token, expected end of statement");
3385 AssemblerOptions.back()->setReorder();
3386 getTargetStreamer().emitDirectiveSetReorder();
3387 Parser.Lex(); // Consume the EndOfStatement.
3391 bool MipsAsmParser::parseSetNoReorderDirective() {
3392 MCAsmParser &Parser = getParser();
3394 // If this is not the end of the statement, report an error.
3395 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3396 reportParseError("unexpected token, expected end of statement");
3399 AssemblerOptions.back()->setNoReorder();
3400 getTargetStreamer().emitDirectiveSetNoReorder();
3401 Parser.Lex(); // Consume the EndOfStatement.
3405 bool MipsAsmParser::parseSetMacroDirective() {
3406 MCAsmParser &Parser = getParser();
3408 // If this is not the end of the statement, report an error.
3409 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3410 reportParseError("unexpected token, expected end of statement");
3413 AssemblerOptions.back()->setMacro();
3414 Parser.Lex(); // Consume the EndOfStatement.
3418 bool MipsAsmParser::parseSetNoMacroDirective() {
3419 MCAsmParser &Parser = getParser();
3421 // If this is not the end of the statement, report an error.
3422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3423 reportParseError("unexpected token, expected end of statement");
3426 if (AssemblerOptions.back()->isReorder()) {
3427 reportParseError("`noreorder' must be set before `nomacro'");
3430 AssemblerOptions.back()->setNoMacro();
3431 Parser.Lex(); // Consume the EndOfStatement.
3435 bool MipsAsmParser::parseSetMsaDirective() {
3436 MCAsmParser &Parser = getParser();
3439 // If this is not the end of the statement, report an error.
3440 if (getLexer().isNot(AsmToken::EndOfStatement))
3441 return reportParseError("unexpected token, expected end of statement");
3443 setFeatureBits(Mips::FeatureMSA, "msa");
3444 getTargetStreamer().emitDirectiveSetMsa();
3448 bool MipsAsmParser::parseSetNoMsaDirective() {
3449 MCAsmParser &Parser = getParser();
3452 // If this is not the end of the statement, report an error.
3453 if (getLexer().isNot(AsmToken::EndOfStatement))
3454 return reportParseError("unexpected token, expected end of statement");
3456 clearFeatureBits(Mips::FeatureMSA, "msa");
3457 getTargetStreamer().emitDirectiveSetNoMsa();
3461 bool MipsAsmParser::parseSetNoDspDirective() {
3462 MCAsmParser &Parser = getParser();
3463 Parser.Lex(); // Eat "nodsp".
3465 // If this is not the end of the statement, report an error.
3466 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3467 reportParseError("unexpected token, expected end of statement");
3471 clearFeatureBits(Mips::FeatureDSP, "dsp");
3472 getTargetStreamer().emitDirectiveSetNoDsp();
3476 bool MipsAsmParser::parseSetMips16Directive() {
3477 MCAsmParser &Parser = getParser();
3478 Parser.Lex(); // Eat "mips16".
3480 // If this is not the end of the statement, report an error.
3481 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3482 reportParseError("unexpected token, expected end of statement");
3486 setFeatureBits(Mips::FeatureMips16, "mips16");
3487 getTargetStreamer().emitDirectiveSetMips16();
3488 Parser.Lex(); // Consume the EndOfStatement.
3492 bool MipsAsmParser::parseSetNoMips16Directive() {
3493 MCAsmParser &Parser = getParser();
3494 Parser.Lex(); // Eat "nomips16".
3496 // If this is not the end of the statement, report an error.
3497 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3498 reportParseError("unexpected token, expected end of statement");
3502 clearFeatureBits(Mips::FeatureMips16, "mips16");
3503 getTargetStreamer().emitDirectiveSetNoMips16();
3504 Parser.Lex(); // Consume the EndOfStatement.
3508 bool MipsAsmParser::parseSetFpDirective() {
3509 MCAsmParser &Parser = getParser();
3510 MipsABIFlagsSection::FpABIKind FpAbiVal;
3511 // Line can be: .set fp=32
3514 Parser.Lex(); // Eat fp token
3515 AsmToken Tok = Parser.getTok();
3516 if (Tok.isNot(AsmToken::Equal)) {
3517 reportParseError("unexpected token, expected equals sign '='");
3520 Parser.Lex(); // Eat '=' token.
3521 Tok = Parser.getTok();
3523 if (!parseFpABIValue(FpAbiVal, ".set"))
3526 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3527 reportParseError("unexpected token, expected end of statement");
3530 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3531 Parser.Lex(); // Consume the EndOfStatement.
3535 bool MipsAsmParser::parseSetPopDirective() {
3536 MCAsmParser &Parser = getParser();
3537 SMLoc Loc = getLexer().getLoc();
3540 if (getLexer().isNot(AsmToken::EndOfStatement))
3541 return reportParseError("unexpected token, expected end of statement");
3543 // Always keep an element on the options "stack" to prevent the user
3544 // from changing the initial options. This is how we remember them.
3545 if (AssemblerOptions.size() == 2)
3546 return reportParseError(Loc, ".set pop with no .set push");
3548 AssemblerOptions.pop_back();
3549 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3551 getTargetStreamer().emitDirectiveSetPop();
3555 bool MipsAsmParser::parseSetPushDirective() {
3556 MCAsmParser &Parser = getParser();
3558 if (getLexer().isNot(AsmToken::EndOfStatement))
3559 return reportParseError("unexpected token, expected end of statement");
3561 // Create a copy of the current assembler options environment and push it.
3562 AssemblerOptions.push_back(
3563 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3565 getTargetStreamer().emitDirectiveSetPush();
3569 bool MipsAsmParser::parseSetAssignment() {
3571 const MCExpr *Value;
3572 MCAsmParser &Parser = getParser();
3574 if (Parser.parseIdentifier(Name))
3575 reportParseError("expected identifier after .set");
3577 if (getLexer().isNot(AsmToken::Comma))
3578 return reportParseError("unexpected token, expected comma");
3581 if (Parser.parseExpression(Value))
3582 return reportParseError("expected valid expression after comma");
3584 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3585 Sym->setVariableValue(Value);
3590 bool MipsAsmParser::parseSetMips0Directive() {
3591 MCAsmParser &Parser = getParser();
3593 if (getLexer().isNot(AsmToken::EndOfStatement))
3594 return reportParseError("unexpected token, expected end of statement");
3596 // Reset assembler options to their initial values.
3597 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3598 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3600 getTargetStreamer().emitDirectiveSetMips0();
3604 bool MipsAsmParser::parseSetArchDirective() {
3605 MCAsmParser &Parser = getParser();
3607 if (getLexer().isNot(AsmToken::Equal))
3608 return reportParseError("unexpected token, expected equals sign");
3612 if (Parser.parseIdentifier(Arch))
3613 return reportParseError("expected arch identifier");
3615 StringRef ArchFeatureName =
3616 StringSwitch<StringRef>(Arch)
3617 .Case("mips1", "mips1")
3618 .Case("mips2", "mips2")
3619 .Case("mips3", "mips3")
3620 .Case("mips4", "mips4")
3621 .Case("mips5", "mips5")
3622 .Case("mips32", "mips32")
3623 .Case("mips32r2", "mips32r2")
3624 .Case("mips32r3", "mips32r3")
3625 .Case("mips32r5", "mips32r5")
3626 .Case("mips32r6", "mips32r6")
3627 .Case("mips64", "mips64")
3628 .Case("mips64r2", "mips64r2")
3629 .Case("mips64r3", "mips64r3")
3630 .Case("mips64r5", "mips64r5")
3631 .Case("mips64r6", "mips64r6")
3632 .Case("cnmips", "cnmips")
3633 .Case("r4000", "mips3") // This is an implementation of Mips3.
3636 if (ArchFeatureName.empty())
3637 return reportParseError("unsupported architecture");
3639 selectArch(ArchFeatureName);
3640 getTargetStreamer().emitDirectiveSetArch(Arch);
3644 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3645 MCAsmParser &Parser = getParser();
3647 if (getLexer().isNot(AsmToken::EndOfStatement))
3648 return reportParseError("unexpected token, expected end of statement");
3652 llvm_unreachable("Unimplemented feature");
3653 case Mips::FeatureDSP:
3654 setFeatureBits(Mips::FeatureDSP, "dsp");
3655 getTargetStreamer().emitDirectiveSetDsp();
3657 case Mips::FeatureMicroMips:
3658 getTargetStreamer().emitDirectiveSetMicroMips();
3660 case Mips::FeatureMips1:
3661 selectArch("mips1");
3662 getTargetStreamer().emitDirectiveSetMips1();
3664 case Mips::FeatureMips2:
3665 selectArch("mips2");
3666 getTargetStreamer().emitDirectiveSetMips2();
3668 case Mips::FeatureMips3:
3669 selectArch("mips3");
3670 getTargetStreamer().emitDirectiveSetMips3();
3672 case Mips::FeatureMips4:
3673 selectArch("mips4");
3674 getTargetStreamer().emitDirectiveSetMips4();
3676 case Mips::FeatureMips5:
3677 selectArch("mips5");
3678 getTargetStreamer().emitDirectiveSetMips5();
3680 case Mips::FeatureMips32:
3681 selectArch("mips32");
3682 getTargetStreamer().emitDirectiveSetMips32();
3684 case Mips::FeatureMips32r2:
3685 selectArch("mips32r2");
3686 getTargetStreamer().emitDirectiveSetMips32R2();
3688 case Mips::FeatureMips32r3:
3689 selectArch("mips32r3");
3690 getTargetStreamer().emitDirectiveSetMips32R3();
3692 case Mips::FeatureMips32r5:
3693 selectArch("mips32r5");
3694 getTargetStreamer().emitDirectiveSetMips32R5();
3696 case Mips::FeatureMips32r6:
3697 selectArch("mips32r6");
3698 getTargetStreamer().emitDirectiveSetMips32R6();
3700 case Mips::FeatureMips64:
3701 selectArch("mips64");
3702 getTargetStreamer().emitDirectiveSetMips64();
3704 case Mips::FeatureMips64r2:
3705 selectArch("mips64r2");
3706 getTargetStreamer().emitDirectiveSetMips64R2();
3708 case Mips::FeatureMips64r3:
3709 selectArch("mips64r3");
3710 getTargetStreamer().emitDirectiveSetMips64R3();
3712 case Mips::FeatureMips64r5:
3713 selectArch("mips64r5");
3714 getTargetStreamer().emitDirectiveSetMips64R5();
3716 case Mips::FeatureMips64r6:
3717 selectArch("mips64r6");
3718 getTargetStreamer().emitDirectiveSetMips64R6();
3724 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3725 MCAsmParser &Parser = getParser();
3726 if (getLexer().isNot(AsmToken::Comma)) {
3727 SMLoc Loc = getLexer().getLoc();
3728 Parser.eatToEndOfStatement();
3729 return Error(Loc, ErrorStr);
3732 Parser.Lex(); // Eat the comma.
3736 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3737 if (AssemblerOptions.back()->isReorder())
3738 Warning(Loc, ".cpload should be inside a noreorder section");
3740 if (inMips16Mode()) {
3741 reportParseError(".cpload is not supported in Mips16 mode");
3745 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3746 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3747 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3748 reportParseError("expected register containing function address");
3752 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3753 if (!RegOpnd.isGPRAsmReg()) {
3754 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3758 // If this is not the end of the statement, report an error.
3759 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3760 reportParseError("unexpected token, expected end of statement");
3764 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3768 bool MipsAsmParser::parseDirectiveCPSetup() {
3769 MCAsmParser &Parser = getParser();
3772 bool SaveIsReg = true;
3774 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3775 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3776 if (ResTy == MatchOperand_NoMatch) {
3777 reportParseError("expected register containing function address");
3778 Parser.eatToEndOfStatement();
3782 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3783 if (!FuncRegOpnd.isGPRAsmReg()) {
3784 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3785 Parser.eatToEndOfStatement();
3789 FuncReg = FuncRegOpnd.getGPR32Reg();
3792 if (!eatComma("unexpected token, expected comma"))
3795 ResTy = parseAnyRegister(TmpReg);
3796 if (ResTy == MatchOperand_NoMatch) {
3797 const AsmToken &Tok = Parser.getTok();
3798 if (Tok.is(AsmToken::Integer)) {
3799 Save = Tok.getIntVal();
3803 reportParseError("expected save register or stack offset");
3804 Parser.eatToEndOfStatement();
3808 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3809 if (!SaveOpnd.isGPRAsmReg()) {
3810 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3811 Parser.eatToEndOfStatement();
3814 Save = SaveOpnd.getGPR32Reg();
3817 if (!eatComma("unexpected token, expected comma"))
3821 if (Parser.parseExpression(Expr)) {
3822 reportParseError("expected expression");
3826 if (Expr->getKind() != MCExpr::SymbolRef) {
3827 reportParseError("expected symbol");
3830 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3832 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3837 bool MipsAsmParser::parseDirectiveNaN() {
3838 MCAsmParser &Parser = getParser();
3839 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3840 const AsmToken &Tok = Parser.getTok();
3842 if (Tok.getString() == "2008") {
3844 getTargetStreamer().emitDirectiveNaN2008();
3846 } else if (Tok.getString() == "legacy") {
3848 getTargetStreamer().emitDirectiveNaNLegacy();
3852 // If we don't recognize the option passed to the .nan
3853 // directive (e.g. no option or unknown option), emit an error.
3854 reportParseError("invalid option in .nan directive");
3858 bool MipsAsmParser::parseDirectiveSet() {
3859 MCAsmParser &Parser = getParser();
3860 // Get the next token.
3861 const AsmToken &Tok = Parser.getTok();
3863 if (Tok.getString() == "noat") {
3864 return parseSetNoAtDirective();
3865 } else if (Tok.getString() == "at") {
3866 return parseSetAtDirective();
3867 } else if (Tok.getString() == "arch") {
3868 return parseSetArchDirective();
3869 } else if (Tok.getString() == "fp") {
3870 return parseSetFpDirective();
3871 } else if (Tok.getString() == "pop") {
3872 return parseSetPopDirective();
3873 } else if (Tok.getString() == "push") {
3874 return parseSetPushDirective();
3875 } else if (Tok.getString() == "reorder") {
3876 return parseSetReorderDirective();
3877 } else if (Tok.getString() == "noreorder") {
3878 return parseSetNoReorderDirective();
3879 } else if (Tok.getString() == "macro") {
3880 return parseSetMacroDirective();
3881 } else if (Tok.getString() == "nomacro") {
3882 return parseSetNoMacroDirective();
3883 } else if (Tok.getString() == "mips16") {
3884 return parseSetMips16Directive();
3885 } else if (Tok.getString() == "nomips16") {
3886 return parseSetNoMips16Directive();
3887 } else if (Tok.getString() == "nomicromips") {
3888 getTargetStreamer().emitDirectiveSetNoMicroMips();
3889 Parser.eatToEndOfStatement();
3891 } else if (Tok.getString() == "micromips") {
3892 return parseSetFeature(Mips::FeatureMicroMips);
3893 } else if (Tok.getString() == "mips0") {
3894 return parseSetMips0Directive();
3895 } else if (Tok.getString() == "mips1") {
3896 return parseSetFeature(Mips::FeatureMips1);
3897 } else if (Tok.getString() == "mips2") {
3898 return parseSetFeature(Mips::FeatureMips2);
3899 } else if (Tok.getString() == "mips3") {
3900 return parseSetFeature(Mips::FeatureMips3);
3901 } else if (Tok.getString() == "mips4") {
3902 return parseSetFeature(Mips::FeatureMips4);
3903 } else if (Tok.getString() == "mips5") {
3904 return parseSetFeature(Mips::FeatureMips5);
3905 } else if (Tok.getString() == "mips32") {
3906 return parseSetFeature(Mips::FeatureMips32);
3907 } else if (Tok.getString() == "mips32r2") {
3908 return parseSetFeature(Mips::FeatureMips32r2);
3909 } else if (Tok.getString() == "mips32r3") {
3910 return parseSetFeature(Mips::FeatureMips32r3);
3911 } else if (Tok.getString() == "mips32r5") {
3912 return parseSetFeature(Mips::FeatureMips32r5);
3913 } else if (Tok.getString() == "mips32r6") {
3914 return parseSetFeature(Mips::FeatureMips32r6);
3915 } else if (Tok.getString() == "mips64") {
3916 return parseSetFeature(Mips::FeatureMips64);
3917 } else if (Tok.getString() == "mips64r2") {
3918 return parseSetFeature(Mips::FeatureMips64r2);
3919 } else if (Tok.getString() == "mips64r3") {
3920 return parseSetFeature(Mips::FeatureMips64r3);
3921 } else if (Tok.getString() == "mips64r5") {
3922 return parseSetFeature(Mips::FeatureMips64r5);
3923 } else if (Tok.getString() == "mips64r6") {
3924 return parseSetFeature(Mips::FeatureMips64r6);
3925 } else if (Tok.getString() == "dsp") {
3926 return parseSetFeature(Mips::FeatureDSP);
3927 } else if (Tok.getString() == "nodsp") {
3928 return parseSetNoDspDirective();
3929 } else if (Tok.getString() == "msa") {
3930 return parseSetMsaDirective();
3931 } else if (Tok.getString() == "nomsa") {
3932 return parseSetNoMsaDirective();
3934 // It is just an identifier, look for an assignment.
3935 parseSetAssignment();
3942 /// parseDataDirective
3943 /// ::= .word [ expression (, expression)* ]
3944 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3945 MCAsmParser &Parser = getParser();
3946 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3948 const MCExpr *Value;
3949 if (getParser().parseExpression(Value))
3952 getParser().getStreamer().EmitValue(Value, Size);
3954 if (getLexer().is(AsmToken::EndOfStatement))
3957 if (getLexer().isNot(AsmToken::Comma))
3958 return Error(L, "unexpected token, expected comma");
3967 /// parseDirectiveGpWord
3968 /// ::= .gpword local_sym
3969 bool MipsAsmParser::parseDirectiveGpWord() {
3970 MCAsmParser &Parser = getParser();
3971 const MCExpr *Value;
3972 // EmitGPRel32Value requires an expression, so we are using base class
3973 // method to evaluate the expression.
3974 if (getParser().parseExpression(Value))
3976 getParser().getStreamer().EmitGPRel32Value(Value);
3978 if (getLexer().isNot(AsmToken::EndOfStatement))
3979 return Error(getLexer().getLoc(),
3980 "unexpected token, expected end of statement");
3981 Parser.Lex(); // Eat EndOfStatement token.
3985 /// parseDirectiveGpDWord
3986 /// ::= .gpdword local_sym
3987 bool MipsAsmParser::parseDirectiveGpDWord() {
3988 MCAsmParser &Parser = getParser();
3989 const MCExpr *Value;
3990 // EmitGPRel64Value requires an expression, so we are using base class
3991 // method to evaluate the expression.
3992 if (getParser().parseExpression(Value))
3994 getParser().getStreamer().EmitGPRel64Value(Value);
3996 if (getLexer().isNot(AsmToken::EndOfStatement))
3997 return Error(getLexer().getLoc(),
3998 "unexpected token, expected end of statement");
3999 Parser.Lex(); // Eat EndOfStatement token.
4003 bool MipsAsmParser::parseDirectiveOption() {
4004 MCAsmParser &Parser = getParser();
4005 // Get the option token.
4006 AsmToken Tok = Parser.getTok();
4007 // At the moment only identifiers are supported.
4008 if (Tok.isNot(AsmToken::Identifier)) {
4009 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4010 Parser.eatToEndOfStatement();
4014 StringRef Option = Tok.getIdentifier();
4016 if (Option == "pic0") {
4017 getTargetStreamer().emitDirectiveOptionPic0();
4019 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4020 Error(Parser.getTok().getLoc(),
4021 "unexpected token, expected end of statement");
4022 Parser.eatToEndOfStatement();
4027 if (Option == "pic2") {
4028 getTargetStreamer().emitDirectiveOptionPic2();
4030 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4031 Error(Parser.getTok().getLoc(),
4032 "unexpected token, expected end of statement");
4033 Parser.eatToEndOfStatement();
4039 Warning(Parser.getTok().getLoc(),
4040 "unknown option, expected 'pic0' or 'pic2'");
4041 Parser.eatToEndOfStatement();
4045 /// parseInsnDirective
4047 bool MipsAsmParser::parseInsnDirective() {
4048 // If this is not the end of the statement, report an error.
4049 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4050 reportParseError("unexpected token, expected end of statement");
4054 // The actual label marking happens in
4055 // MipsELFStreamer::createPendingLabelRelocs().
4056 getTargetStreamer().emitDirectiveInsn();
4058 getParser().Lex(); // Eat EndOfStatement token.
4062 /// parseDirectiveModule
4063 /// ::= .module oddspreg
4064 /// ::= .module nooddspreg
4065 /// ::= .module fp=value
4066 bool MipsAsmParser::parseDirectiveModule() {
4067 MCAsmParser &Parser = getParser();
4068 MCAsmLexer &Lexer = getLexer();
4069 SMLoc L = Lexer.getLoc();
4071 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4072 // TODO : get a better message.
4073 reportParseError(".module directive must appear before any code");
4078 if (Parser.parseIdentifier(Option)) {
4079 reportParseError("expected .module option identifier");
4083 if (Option == "oddspreg") {
4084 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4085 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4087 // If this is not the end of the statement, report an error.
4088 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4089 reportParseError("unexpected token, expected end of statement");
4093 return false; // parseDirectiveModule has finished successfully.
4094 } else if (Option == "nooddspreg") {
4096 Error(L, "'.module nooddspreg' requires the O32 ABI");
4100 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4101 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4103 // If this is not the end of the statement, report an error.
4104 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4105 reportParseError("unexpected token, expected end of statement");
4109 return false; // parseDirectiveModule has finished successfully.
4110 } else if (Option == "fp") {
4111 return parseDirectiveModuleFP();
4113 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4117 /// parseDirectiveModuleFP
4121 bool MipsAsmParser::parseDirectiveModuleFP() {
4122 MCAsmParser &Parser = getParser();
4123 MCAsmLexer &Lexer = getLexer();
4125 if (Lexer.isNot(AsmToken::Equal)) {
4126 reportParseError("unexpected token, expected equals sign '='");
4129 Parser.Lex(); // Eat '=' token.
4131 MipsABIFlagsSection::FpABIKind FpABI;
4132 if (!parseFpABIValue(FpABI, ".module"))
4135 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4136 reportParseError("unexpected token, expected end of statement");
4140 // Emit appropriate flags.
4141 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4142 Parser.Lex(); // Consume the EndOfStatement.
4146 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4147 StringRef Directive) {
4148 MCAsmParser &Parser = getParser();
4149 MCAsmLexer &Lexer = getLexer();
4151 if (Lexer.is(AsmToken::Identifier)) {
4152 StringRef Value = Parser.getTok().getString();
4155 if (Value != "xx") {
4156 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4161 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4165 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4169 if (Lexer.is(AsmToken::Integer)) {
4170 unsigned Value = Parser.getTok().getIntVal();
4173 if (Value != 32 && Value != 64) {
4174 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4180 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4184 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4186 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4194 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4195 MCAsmParser &Parser = getParser();
4196 StringRef IDVal = DirectiveID.getString();
4198 if (IDVal == ".cpload")
4199 return parseDirectiveCpLoad(DirectiveID.getLoc());
4200 if (IDVal == ".dword") {
4201 parseDataDirective(8, DirectiveID.getLoc());
4204 if (IDVal == ".ent") {
4205 StringRef SymbolName;
4207 if (Parser.parseIdentifier(SymbolName)) {
4208 reportParseError("expected identifier after .ent");
4212 // There's an undocumented extension that allows an integer to
4213 // follow the name of the procedure which AFAICS is ignored by GAS.
4214 // Example: .ent foo,2
4215 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4216 if (getLexer().isNot(AsmToken::Comma)) {
4217 // Even though we accept this undocumented extension for compatibility
4218 // reasons, the additional integer argument does not actually change
4219 // the behaviour of the '.ent' directive, so we would like to discourage
4220 // its use. We do this by not referring to the extended version in
4221 // error messages which are not directly related to its use.
4222 reportParseError("unexpected token, expected end of statement");
4225 Parser.Lex(); // Eat the comma.
4226 const MCExpr *DummyNumber;
4227 int64_t DummyNumberVal;
4228 // If the user was explicitly trying to use the extended version,
4229 // we still give helpful extension-related error messages.
4230 if (Parser.parseExpression(DummyNumber)) {
4231 reportParseError("expected number after comma");
4234 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4235 reportParseError("expected an absolute expression after comma");
4240 // If this is not the end of the statement, report an error.
4241 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4242 reportParseError("unexpected token, expected end of statement");
4246 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4248 getTargetStreamer().emitDirectiveEnt(*Sym);
4253 if (IDVal == ".end") {
4254 StringRef SymbolName;
4256 if (Parser.parseIdentifier(SymbolName)) {
4257 reportParseError("expected identifier after .end");
4261 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4262 reportParseError("unexpected token, expected end of statement");
4266 if (CurrentFn == nullptr) {
4267 reportParseError(".end used without .ent");
4271 if ((SymbolName != CurrentFn->getName())) {
4272 reportParseError(".end symbol does not match .ent symbol");
4276 getTargetStreamer().emitDirectiveEnd(SymbolName);
4277 CurrentFn = nullptr;
4281 if (IDVal == ".frame") {
4282 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4283 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4284 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4285 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4286 reportParseError("expected stack register");
4290 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4291 if (!StackRegOpnd.isGPRAsmReg()) {
4292 reportParseError(StackRegOpnd.getStartLoc(),
4293 "expected general purpose register");
4296 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4298 if (Parser.getTok().is(AsmToken::Comma))
4301 reportParseError("unexpected token, expected comma");
4305 // Parse the frame size.
4306 const MCExpr *FrameSize;
4307 int64_t FrameSizeVal;
4309 if (Parser.parseExpression(FrameSize)) {
4310 reportParseError("expected frame size value");
4314 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4315 reportParseError("frame size not an absolute expression");
4319 if (Parser.getTok().is(AsmToken::Comma))
4322 reportParseError("unexpected token, expected comma");
4326 // Parse the return register.
4328 ResTy = parseAnyRegister(TmpReg);
4329 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4330 reportParseError("expected return register");
4334 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4335 if (!ReturnRegOpnd.isGPRAsmReg()) {
4336 reportParseError(ReturnRegOpnd.getStartLoc(),
4337 "expected general purpose register");
4341 // If this is not the end of the statement, report an error.
4342 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4343 reportParseError("unexpected token, expected end of statement");
4347 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4348 ReturnRegOpnd.getGPR32Reg());
4352 if (IDVal == ".set") {
4353 return parseDirectiveSet();
4356 if (IDVal == ".mask" || IDVal == ".fmask") {
4357 // .mask bitmask, frame_offset
4358 // bitmask: One bit for each register used.
4359 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4360 // first register is expected to be saved.
4362 // .mask 0x80000000, -4
4363 // .fmask 0x80000000, -4
4366 // Parse the bitmask
4367 const MCExpr *BitMask;
4370 if (Parser.parseExpression(BitMask)) {
4371 reportParseError("expected bitmask value");
4375 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4376 reportParseError("bitmask not an absolute expression");
4380 if (Parser.getTok().is(AsmToken::Comma))
4383 reportParseError("unexpected token, expected comma");
4387 // Parse the frame_offset
4388 const MCExpr *FrameOffset;
4389 int64_t FrameOffsetVal;
4391 if (Parser.parseExpression(FrameOffset)) {
4392 reportParseError("expected frame offset value");
4396 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4397 reportParseError("frame offset not an absolute expression");
4401 // If this is not the end of the statement, report an error.
4402 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4403 reportParseError("unexpected token, expected end of statement");
4407 if (IDVal == ".mask")
4408 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4410 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4414 if (IDVal == ".nan")
4415 return parseDirectiveNaN();
4417 if (IDVal == ".gpword") {
4418 parseDirectiveGpWord();
4422 if (IDVal == ".gpdword") {
4423 parseDirectiveGpDWord();
4427 if (IDVal == ".word") {
4428 parseDataDirective(4, DirectiveID.getLoc());
4432 if (IDVal == ".option")
4433 return parseDirectiveOption();
4435 if (IDVal == ".abicalls") {
4436 getTargetStreamer().emitDirectiveAbiCalls();
4437 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4438 Error(Parser.getTok().getLoc(),
4439 "unexpected token, expected end of statement");
4441 Parser.eatToEndOfStatement();
4446 if (IDVal == ".cpsetup")
4447 return parseDirectiveCPSetup();
4449 if (IDVal == ".module")
4450 return parseDirectiveModule();
4452 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4453 return parseInternalDirectiveReallowModule();
4455 if (IDVal == ".insn")
4456 return parseInsnDirective();
4461 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4462 // If this is not the end of the statement, report an error.
4463 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4464 reportParseError("unexpected token, expected end of statement");
4468 getTargetStreamer().reallowModuleDirective();
4470 getParser().Lex(); // Eat EndOfStatement token.
4474 extern "C" void LLVMInitializeMipsAsmParser() {
4475 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4476 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4477 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4478 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4481 #define GET_REGISTER_MATCHER
4482 #define GET_MATCHER_IMPLEMENTATION
4483 #include "MipsGenAsmMatcher.inc"