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 createShiftOr(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 createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1658 SmallVectorImpl<MCInst> &Instructions) {
1659 createShiftOr<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 tmpInst.setLoc(IDLoc);
1717 // FIXME: gas has a special case for values that are 000...1111, which
1718 // becomes a li -1 and then a dsrl
1719 if (0 <= ImmValue && ImmValue <= 65535) {
1720 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1721 // li d,j => ori d,$zero,j
1722 tmpInst.setOpcode(Mips::ORi);
1723 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1724 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1725 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1726 Instructions.push_back(tmpInst);
1727 } else if (ImmValue < 0 && ImmValue >= -32768) {
1728 // For negative signed 16-bit values (-32768 <= j < 0):
1729 // li d,j => addiu d,$zero,j
1730 tmpInst.setOpcode(Mips::ADDiu);
1731 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1732 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1733 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1734 Instructions.push_back(tmpInst);
1735 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1736 // For all other values which are representable as a 32-bit integer:
1737 // li d,j => lui d,hi16(j)
1739 tmpInst.setOpcode(Mips::LUi);
1740 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1741 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1742 Instructions.push_back(tmpInst);
1743 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1744 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1746 Error(IDLoc, "instruction requires a 64-bit architecture");
1750 // <------- lo32 ------>
1751 // <------- hi32 ------>
1752 // <- hi16 -> <- lo16 ->
1753 // _________________________________
1755 // | 16-bytes | 16-bytes | 16-bytes |
1756 // |__________|__________|__________|
1758 // For any 64-bit value that is representable as a 48-bit integer:
1759 // li d,j => lui d,hi16(j)
1760 // ori d,d,hi16(lo32(j))
1762 // ori d,d,lo16(lo32(j))
1763 tmpInst.setOpcode(Mips::LUi);
1764 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1766 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1767 Instructions.push_back(tmpInst);
1768 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1769 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1772 Error(IDLoc, "instruction requires a 64-bit architecture");
1776 // <------- hi32 ------> <------- lo32 ------>
1777 // <- hi16 -> <- lo16 ->
1778 // ___________________________________________
1780 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1781 // |__________|__________|__________|__________|
1783 // For all other values which are representable as a 64-bit integer:
1784 // li d,j => lui d,hi16(j)
1785 // ori d,d,lo16(hi32(j))
1787 // ori d,d,hi16(lo32(j))
1789 // ori d,d,lo16(lo32(j))
1790 tmpInst.setOpcode(Mips::LUi);
1791 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1793 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1794 Instructions.push_back(tmpInst);
1795 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1796 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1797 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1803 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1804 SmallVectorImpl<MCInst> &Instructions) {
1806 const MCOperand &ImmOp = Inst.getOperand(2);
1807 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1808 "expected immediate operand kind");
1809 if (!ImmOp.isImm()) {
1810 expandLoadAddressSym(Inst, IDLoc, Instructions);
1813 const MCOperand &SrcRegOp = Inst.getOperand(1);
1814 assert(SrcRegOp.isReg() && "expected register operand kind");
1815 const MCOperand &DstRegOp = Inst.getOperand(0);
1816 assert(DstRegOp.isReg() && "expected register operand kind");
1817 int ImmValue = ImmOp.getImm();
1818 if (-32768 <= ImmValue && ImmValue <= 65535) {
1819 // For -32768 <= j <= 65535.
1820 // la d,j(s) => addiu d,s,j
1821 tmpInst.setOpcode(Mips::ADDiu);
1822 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1823 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1824 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1825 Instructions.push_back(tmpInst);
1827 // For any other value of j that is representable as a 32-bit integer.
1828 // la d,j(s) => lui d,hi16(j)
1831 tmpInst.setOpcode(Mips::LUi);
1832 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1833 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1834 Instructions.push_back(tmpInst);
1836 tmpInst.setOpcode(Mips::ORi);
1837 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1838 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1839 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1840 Instructions.push_back(tmpInst);
1842 tmpInst.setOpcode(Mips::ADDu);
1843 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1844 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1845 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1846 Instructions.push_back(tmpInst);
1852 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1853 SmallVectorImpl<MCInst> &Instructions) {
1855 const MCOperand &ImmOp = Inst.getOperand(1);
1856 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1857 "expected immediate operand kind");
1858 if (!ImmOp.isImm()) {
1859 expandLoadAddressSym(Inst, IDLoc, Instructions);
1862 const MCOperand &RegOp = Inst.getOperand(0);
1863 assert(RegOp.isReg() && "expected register operand kind");
1864 int ImmValue = ImmOp.getImm();
1865 if (-32768 <= ImmValue && ImmValue <= 65535) {
1866 // For -32768 <= j <= 65535.
1867 // la d,j => addiu d,$zero,j
1868 tmpInst.setOpcode(Mips::ADDiu);
1869 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1870 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1871 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1872 Instructions.push_back(tmpInst);
1874 // For any other value of j that is representable as a 32-bit integer.
1875 // la d,j => lui d,hi16(j)
1877 tmpInst.setOpcode(Mips::LUi);
1878 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1879 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1880 Instructions.push_back(tmpInst);
1882 tmpInst.setOpcode(Mips::ORi);
1883 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1884 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1885 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1886 Instructions.push_back(tmpInst);
1892 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1893 SmallVectorImpl<MCInst> &Instructions) {
1894 // FIXME: If we do have a valid at register to use, we should generate a
1895 // slightly shorter sequence here.
1897 int ExprOperandNo = 1;
1898 // Sometimes the assembly parser will get the immediate expression as
1899 // a $zero + an immediate.
1900 if (Inst.getNumOperands() == 3) {
1901 assert(Inst.getOperand(1).getReg() ==
1902 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1905 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1906 assert(SymOp.isExpr() && "expected symbol operand kind");
1907 const MCOperand &RegOp = Inst.getOperand(0);
1908 unsigned RegNo = RegOp.getReg();
1909 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1910 const MCSymbolRefExpr *HiExpr =
1911 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1912 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1913 const MCSymbolRefExpr *LoExpr =
1914 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1915 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1917 // If it's a 64-bit architecture, expand to:
1918 // la d,sym => lui d,highest(sym)
1919 // ori d,d,higher(sym)
1921 // ori d,d,hi16(sym)
1923 // ori d,d,lo16(sym)
1924 const MCSymbolRefExpr *HighestExpr =
1925 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1926 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1927 const MCSymbolRefExpr *HigherExpr =
1928 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1929 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1931 tmpInst.setOpcode(Mips::LUi);
1932 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1933 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1934 Instructions.push_back(tmpInst);
1936 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1938 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1940 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1943 // Otherwise, expand to:
1944 // la d,sym => lui d,hi16(sym)
1945 // ori d,d,lo16(sym)
1946 tmpInst.setOpcode(Mips::LUi);
1947 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1948 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1949 Instructions.push_back(tmpInst);
1951 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1956 bool MipsAsmParser::expandUncondBranchMMPseudo(
1957 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1958 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1959 "unexpected number of operands");
1961 MCOperand Offset = Inst.getOperand(0);
1962 if (Offset.isExpr()) {
1964 Inst.setOpcode(Mips::BEQ_MM);
1965 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1966 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1967 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1969 assert(Offset.isImm() && "expected immediate operand kind");
1970 if (isIntN(11, Offset.getImm())) {
1971 // If offset fits into 11 bits then this instruction becomes microMIPS
1972 // 16-bit unconditional branch instruction.
1973 Inst.setOpcode(Mips::B16_MM);
1975 if (!isIntN(17, Offset.getImm()))
1976 Error(IDLoc, "branch target out of range");
1977 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1978 Error(IDLoc, "branch to misaligned address");
1980 Inst.setOpcode(Mips::BEQ_MM);
1981 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1982 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1983 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1986 Instructions.push_back(Inst);
1988 // If .set reorder is active, emit a NOP after the branch instruction.
1989 if (AssemblerOptions.back()->isReorder())
1990 createNop(true, IDLoc, Instructions);
1995 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1996 SmallVectorImpl<MCInst> &Instructions,
1997 bool isLoad, bool isImmOpnd) {
1998 const MCSymbolRefExpr *SR;
2000 unsigned ImmOffset, HiOffset, LoOffset;
2001 const MCExpr *ExprOffset;
2003 // 1st operand is either the source or destination register.
2004 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2005 unsigned RegOpNum = Inst.getOperand(0).getReg();
2006 // 2nd operand is the base register.
2007 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2008 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2009 // 3rd operand is either an immediate or expression.
2011 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2012 ImmOffset = Inst.getOperand(2).getImm();
2013 LoOffset = ImmOffset & 0x0000ffff;
2014 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2015 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2016 if (LoOffset & 0x8000)
2019 ExprOffset = Inst.getOperand(2).getExpr();
2020 // All instructions will have the same location.
2021 TempInst.setLoc(IDLoc);
2022 // These are some of the types of expansions we perform here:
2023 // 1) lw $8, sym => lui $8, %hi(sym)
2024 // lw $8, %lo(sym)($8)
2025 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2027 // lw $8, %lo(offset)($9)
2028 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2030 // lw $8, %lo(offset)($at)
2031 // 4) sw $8, sym => lui $at, %hi(sym)
2032 // sw $8, %lo(sym)($at)
2033 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2035 // sw $8, %lo(offset)($at)
2036 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2037 // ldc1 $f0, %lo(sym)($at)
2039 // For load instructions we can use the destination register as a temporary
2040 // if base and dst are different (examples 1 and 2) and if the base register
2041 // is general purpose otherwise we must use $at (example 6) and error if it's
2042 // not available. For stores we must use $at (examples 4 and 5) because we
2043 // must not clobber the source register setting up the offset.
2044 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2045 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2046 unsigned RegClassIDOp0 =
2047 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2048 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2049 (RegClassIDOp0 == Mips::GPR64RegClassID);
2050 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2051 TmpRegNum = RegOpNum;
2053 // At this point we need AT to perform the expansions and we exit if it is
2055 TmpRegNum = getATReg(IDLoc);
2060 TempInst.setOpcode(Mips::LUi);
2061 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2063 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2065 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2066 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2067 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2068 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2070 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2072 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2073 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2076 // Add the instruction to the list.
2077 Instructions.push_back(TempInst);
2078 // Prepare TempInst for next instruction.
2080 // Add temp register to base.
2081 if (BaseRegNum != Mips::ZERO) {
2082 TempInst.setOpcode(Mips::ADDu);
2083 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2084 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2085 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2086 Instructions.push_back(TempInst);
2089 // And finally, create original instruction with low part
2090 // of offset and new base.
2091 TempInst.setOpcode(Inst.getOpcode());
2092 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2093 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2095 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2097 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2098 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2099 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2101 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2103 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2104 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2107 Instructions.push_back(TempInst);
2112 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2113 SmallVectorImpl<MCInst> &Instructions) {
2114 unsigned OpNum = Inst.getNumOperands();
2115 unsigned Opcode = Inst.getOpcode();
2116 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2118 assert (Inst.getOperand(OpNum - 1).isImm() &&
2119 Inst.getOperand(OpNum - 2).isReg() &&
2120 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2122 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2123 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2124 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2125 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2126 // It can be implemented as SWM16 or LWM16 instruction.
2127 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2129 Inst.setOpcode(NewOpcode);
2130 Instructions.push_back(Inst);
2134 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2135 SmallVectorImpl<MCInst> &Instructions) {
2137 if (hasShortDelaySlot) {
2138 NopInst.setOpcode(Mips::MOVE16_MM);
2139 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2140 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2142 NopInst.setOpcode(Mips::SLL);
2143 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2144 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2145 NopInst.addOperand(MCOperand::CreateImm(0));
2147 Instructions.push_back(NopInst);
2150 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2151 // As described by the Mips32r2 spec, the registers Rd and Rs for
2152 // jalr.hb must be different.
2153 unsigned Opcode = Inst.getOpcode();
2155 if (Opcode == Mips::JALR_HB &&
2156 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2157 return Match_RequiresDifferentSrcAndDst;
2159 return Match_Success;
2162 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2163 OperandVector &Operands,
2165 uint64_t &ErrorInfo,
2166 bool MatchingInlineAsm) {
2169 SmallVector<MCInst, 8> Instructions;
2170 unsigned MatchResult =
2171 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2173 switch (MatchResult) {
2174 case Match_Success: {
2175 if (processInstruction(Inst, IDLoc, Instructions))
2177 for (unsigned i = 0; i < Instructions.size(); i++)
2178 Out.EmitInstruction(Instructions[i], STI);
2181 case Match_MissingFeature:
2182 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2184 case Match_InvalidOperand: {
2185 SMLoc ErrorLoc = IDLoc;
2186 if (ErrorInfo != ~0ULL) {
2187 if (ErrorInfo >= Operands.size())
2188 return Error(IDLoc, "too few operands for instruction");
2190 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2191 if (ErrorLoc == SMLoc())
2195 return Error(ErrorLoc, "invalid operand for instruction");
2197 case Match_MnemonicFail:
2198 return Error(IDLoc, "invalid instruction");
2199 case Match_RequiresDifferentSrcAndDst:
2200 return Error(IDLoc, "source and destination must be different");
2203 llvm_unreachable("Implement any new match types added!");
2206 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2207 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2208 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2209 ") without \".set noat\"");
2213 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2214 SMRange Range, bool ShowColors) {
2215 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2216 Range, SMFixIt(Range, FixMsg),
2220 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2223 CC = StringSwitch<unsigned>(Name)
2259 if (!(isABI_N32() || isABI_N64()))
2262 if (12 <= CC && CC <= 15) {
2263 // Name is one of t4-t7
2264 AsmToken RegTok = getLexer().peekTok();
2265 SMRange RegRange = RegTok.getLocRange();
2267 StringRef FixedName = StringSwitch<StringRef>(Name)
2273 assert(FixedName != "" && "Register name is not one of t4-t7.");
2275 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2276 "Did you mean $" + FixedName + "?", RegRange);
2279 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2280 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2281 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2282 if (8 <= CC && CC <= 11)
2286 CC = StringSwitch<unsigned>(Name)
2298 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2301 CC = StringSwitch<unsigned>(Name)
2302 .Case("hwr_cpunum", 0)
2303 .Case("hwr_synci_step", 1)
2305 .Case("hwr_ccres", 3)
2306 .Case("hwr_ulr", 29)
2312 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2314 if (Name[0] == 'f') {
2315 StringRef NumString = Name.substr(1);
2317 if (NumString.getAsInteger(10, IntVal))
2318 return -1; // This is not an integer.
2319 if (IntVal > 31) // Maximum index for fpu register.
2326 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2328 if (Name.startswith("fcc")) {
2329 StringRef NumString = Name.substr(3);
2331 if (NumString.getAsInteger(10, IntVal))
2332 return -1; // This is not an integer.
2333 if (IntVal > 7) // There are only 8 fcc registers.
2340 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2342 if (Name.startswith("ac")) {
2343 StringRef NumString = Name.substr(2);
2345 if (NumString.getAsInteger(10, IntVal))
2346 return -1; // This is not an integer.
2347 if (IntVal > 3) // There are only 3 acc registers.
2354 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2357 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2366 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2369 CC = StringSwitch<unsigned>(Name)
2372 .Case("msaaccess", 2)
2374 .Case("msamodify", 4)
2375 .Case("msarequest", 5)
2377 .Case("msaunmap", 7)
2383 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2384 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2386 reportParseError(Loc,
2387 "pseudo-instruction requires $at, which is not available");
2390 unsigned AT = getReg(
2391 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2395 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2396 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2399 unsigned MipsAsmParser::getGPR(int RegNo) {
2400 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2404 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2406 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2409 return getReg(RegClass, RegNum);
2412 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2413 MCAsmParser &Parser = getParser();
2414 DEBUG(dbgs() << "parseOperand\n");
2416 // Check if the current operand has a custom associated parser, if so, try to
2417 // custom parse the operand, or fallback to the general approach.
2418 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2419 if (ResTy == MatchOperand_Success)
2421 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2422 // there was a match, but an error occurred, in which case, just return that
2423 // the operand parsing failed.
2424 if (ResTy == MatchOperand_ParseFail)
2427 DEBUG(dbgs() << ".. Generic Parser\n");
2429 switch (getLexer().getKind()) {
2431 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2433 case AsmToken::Dollar: {
2434 // Parse the register.
2435 SMLoc S = Parser.getTok().getLoc();
2437 // Almost all registers have been parsed by custom parsers. There is only
2438 // one exception to this. $zero (and it's alias $0) will reach this point
2439 // for div, divu, and similar instructions because it is not an operand
2440 // to the instruction definition but an explicit register. Special case
2441 // this situation for now.
2442 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2445 // Maybe it is a symbol reference.
2446 StringRef Identifier;
2447 if (Parser.parseIdentifier(Identifier))
2450 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2451 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2452 // Otherwise create a symbol reference.
2454 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2456 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2459 // Else drop to expression parsing.
2460 case AsmToken::LParen:
2461 case AsmToken::Minus:
2462 case AsmToken::Plus:
2463 case AsmToken::Integer:
2464 case AsmToken::Tilde:
2465 case AsmToken::String: {
2466 DEBUG(dbgs() << ".. generic integer\n");
2467 OperandMatchResultTy ResTy = parseImm(Operands);
2468 return ResTy != MatchOperand_Success;
2470 case AsmToken::Percent: {
2471 // It is a symbol reference or constant expression.
2472 const MCExpr *IdVal;
2473 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2474 if (parseRelocOperand(IdVal))
2477 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2479 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2481 } // case AsmToken::Percent
2482 } // switch(getLexer().getKind())
2486 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2487 StringRef RelocStr) {
2489 // Check the type of the expression.
2490 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2491 // It's a constant, evaluate reloc value.
2493 switch (getVariantKind(RelocStr)) {
2494 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2495 // Get the 1st 16-bits.
2496 Val = MCE->getValue() & 0xffff;
2498 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2499 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2500 // 16 bits being negative.
2501 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2503 case MCSymbolRefExpr::VK_Mips_HIGHER:
2504 // Get the 3rd 16-bits.
2505 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2507 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2508 // Get the 4th 16-bits.
2509 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2512 report_fatal_error("unsupported reloc value");
2514 return MCConstantExpr::Create(Val, getContext());
2517 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2518 // It's a symbol, create a symbolic expression from the symbol.
2519 StringRef Symbol = MSRE->getSymbol().getName();
2520 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2521 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2525 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2526 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2528 // Try to create target expression.
2529 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2530 return MipsMCExpr::Create(VK, Expr, getContext());
2532 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2533 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2534 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2538 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2539 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2540 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2543 // Just return the original expression.
2547 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2549 switch (Expr->getKind()) {
2550 case MCExpr::Constant:
2552 case MCExpr::SymbolRef:
2553 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2554 case MCExpr::Binary:
2555 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2556 if (!isEvaluated(BE->getLHS()))
2558 return isEvaluated(BE->getRHS());
2561 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2562 case MCExpr::Target:
2568 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2569 MCAsmParser &Parser = getParser();
2570 Parser.Lex(); // Eat the % token.
2571 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2572 if (Tok.isNot(AsmToken::Identifier))
2575 std::string Str = Tok.getIdentifier();
2577 Parser.Lex(); // Eat the identifier.
2578 // Now make an expression from the rest of the operand.
2579 const MCExpr *IdVal;
2582 if (getLexer().getKind() == AsmToken::LParen) {
2584 Parser.Lex(); // Eat the '(' token.
2585 if (getLexer().getKind() == AsmToken::Percent) {
2586 Parser.Lex(); // Eat the % token.
2587 const AsmToken &nextTok = Parser.getTok();
2588 if (nextTok.isNot(AsmToken::Identifier))
2591 Str += nextTok.getIdentifier();
2592 Parser.Lex(); // Eat the identifier.
2593 if (getLexer().getKind() != AsmToken::LParen)
2598 if (getParser().parseParenExpression(IdVal, EndLoc))
2601 while (getLexer().getKind() == AsmToken::RParen)
2602 Parser.Lex(); // Eat the ')' token.
2605 return true; // Parenthesis must follow the relocation operand.
2607 Res = evaluateRelocExpr(IdVal, Str);
2611 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2613 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2614 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2615 if (ResTy == MatchOperand_Success) {
2616 assert(Operands.size() == 1);
2617 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2618 StartLoc = Operand.getStartLoc();
2619 EndLoc = Operand.getEndLoc();
2621 // AFAIK, we only support numeric registers and named GPR's in CFI
2623 // Don't worry about eating tokens before failing. Using an unrecognised
2624 // register is a parse error.
2625 if (Operand.isGPRAsmReg()) {
2626 // Resolve to GPR32 or GPR64 appropriately.
2627 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2630 return (RegNo == (unsigned)-1);
2633 assert(Operands.size() == 0);
2634 return (RegNo == (unsigned)-1);
2637 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2638 MCAsmParser &Parser = getParser();
2642 while (getLexer().getKind() == AsmToken::LParen)
2645 switch (getLexer().getKind()) {
2648 case AsmToken::Identifier:
2649 case AsmToken::LParen:
2650 case AsmToken::Integer:
2651 case AsmToken::Minus:
2652 case AsmToken::Plus:
2654 Result = getParser().parseParenExpression(Res, S);
2656 Result = (getParser().parseExpression(Res));
2657 while (getLexer().getKind() == AsmToken::RParen)
2660 case AsmToken::Percent:
2661 Result = parseRelocOperand(Res);
2666 MipsAsmParser::OperandMatchResultTy
2667 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2668 MCAsmParser &Parser = getParser();
2669 DEBUG(dbgs() << "parseMemOperand\n");
2670 const MCExpr *IdVal = nullptr;
2672 bool isParenExpr = false;
2673 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2674 // First operand is the offset.
2675 S = Parser.getTok().getLoc();
2677 if (getLexer().getKind() == AsmToken::LParen) {
2682 if (getLexer().getKind() != AsmToken::Dollar) {
2683 if (parseMemOffset(IdVal, isParenExpr))
2684 return MatchOperand_ParseFail;
2686 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2687 if (Tok.isNot(AsmToken::LParen)) {
2688 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2689 if (Mnemonic.getToken() == "la") {
2691 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2692 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2693 return MatchOperand_Success;
2695 if (Tok.is(AsmToken::EndOfStatement)) {
2697 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2699 // Zero register assumed, add a memory operand with ZERO as its base.
2700 // "Base" will be managed by k_Memory.
2701 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2704 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2705 return MatchOperand_Success;
2707 Error(Parser.getTok().getLoc(), "'(' expected");
2708 return MatchOperand_ParseFail;
2711 Parser.Lex(); // Eat the '(' token.
2714 Res = parseAnyRegister(Operands);
2715 if (Res != MatchOperand_Success)
2718 if (Parser.getTok().isNot(AsmToken::RParen)) {
2719 Error(Parser.getTok().getLoc(), "')' expected");
2720 return MatchOperand_ParseFail;
2723 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2725 Parser.Lex(); // Eat the ')' token.
2728 IdVal = MCConstantExpr::Create(0, getContext());
2730 // Replace the register operand with the memory operand.
2731 std::unique_ptr<MipsOperand> op(
2732 static_cast<MipsOperand *>(Operands.back().release()));
2733 // Remove the register from the operands.
2734 // "op" will be managed by k_Memory.
2735 Operands.pop_back();
2736 // Add the memory operand.
2737 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2739 if (IdVal->EvaluateAsAbsolute(Imm))
2740 IdVal = MCConstantExpr::Create(Imm, getContext());
2741 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2742 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2746 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2747 return MatchOperand_Success;
2750 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2751 MCAsmParser &Parser = getParser();
2752 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2754 SMLoc S = Parser.getTok().getLoc();
2756 if (Sym->isVariable())
2757 Expr = Sym->getVariableValue();
2760 if (Expr->getKind() == MCExpr::SymbolRef) {
2761 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2762 StringRef DefSymbol = Ref->getSymbol().getName();
2763 if (DefSymbol.startswith("$")) {
2764 OperandMatchResultTy ResTy =
2765 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2766 if (ResTy == MatchOperand_Success) {
2769 } else if (ResTy == MatchOperand_ParseFail)
2770 llvm_unreachable("Should never ParseFail");
2773 } else if (Expr->getKind() == MCExpr::Constant) {
2775 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2777 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2784 MipsAsmParser::OperandMatchResultTy
2785 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2786 StringRef Identifier,
2788 int Index = matchCPURegisterName(Identifier);
2790 Operands.push_back(MipsOperand::createGPRReg(
2791 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2792 return MatchOperand_Success;
2795 Index = matchHWRegsRegisterName(Identifier);
2797 Operands.push_back(MipsOperand::createHWRegsReg(
2798 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2799 return MatchOperand_Success;
2802 Index = matchFPURegisterName(Identifier);
2804 Operands.push_back(MipsOperand::createFGRReg(
2805 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2806 return MatchOperand_Success;
2809 Index = matchFCCRegisterName(Identifier);
2811 Operands.push_back(MipsOperand::createFCCReg(
2812 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2813 return MatchOperand_Success;
2816 Index = matchACRegisterName(Identifier);
2818 Operands.push_back(MipsOperand::createACCReg(
2819 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2820 return MatchOperand_Success;
2823 Index = matchMSA128RegisterName(Identifier);
2825 Operands.push_back(MipsOperand::createMSA128Reg(
2826 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2827 return MatchOperand_Success;
2830 Index = matchMSA128CtrlRegisterName(Identifier);
2832 Operands.push_back(MipsOperand::createMSACtrlReg(
2833 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2834 return MatchOperand_Success;
2837 return MatchOperand_NoMatch;
2840 MipsAsmParser::OperandMatchResultTy
2841 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2842 MCAsmParser &Parser = getParser();
2843 auto Token = Parser.getLexer().peekTok(false);
2845 if (Token.is(AsmToken::Identifier)) {
2846 DEBUG(dbgs() << ".. identifier\n");
2847 StringRef Identifier = Token.getIdentifier();
2848 OperandMatchResultTy ResTy =
2849 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2851 } else if (Token.is(AsmToken::Integer)) {
2852 DEBUG(dbgs() << ".. integer\n");
2853 Operands.push_back(MipsOperand::createNumericReg(
2854 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2856 return MatchOperand_Success;
2859 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2861 return MatchOperand_NoMatch;
2864 MipsAsmParser::OperandMatchResultTy
2865 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2866 MCAsmParser &Parser = getParser();
2867 DEBUG(dbgs() << "parseAnyRegister\n");
2869 auto Token = Parser.getTok();
2871 SMLoc S = Token.getLoc();
2873 if (Token.isNot(AsmToken::Dollar)) {
2874 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2875 if (Token.is(AsmToken::Identifier)) {
2876 if (searchSymbolAlias(Operands))
2877 return MatchOperand_Success;
2879 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2880 return MatchOperand_NoMatch;
2882 DEBUG(dbgs() << ".. $\n");
2884 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2885 if (ResTy == MatchOperand_Success) {
2887 Parser.Lex(); // identifier
2892 MipsAsmParser::OperandMatchResultTy
2893 MipsAsmParser::parseImm(OperandVector &Operands) {
2894 MCAsmParser &Parser = getParser();
2895 switch (getLexer().getKind()) {
2897 return MatchOperand_NoMatch;
2898 case AsmToken::LParen:
2899 case AsmToken::Minus:
2900 case AsmToken::Plus:
2901 case AsmToken::Integer:
2902 case AsmToken::Tilde:
2903 case AsmToken::String:
2907 const MCExpr *IdVal;
2908 SMLoc S = Parser.getTok().getLoc();
2909 if (getParser().parseExpression(IdVal))
2910 return MatchOperand_ParseFail;
2912 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2913 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2914 return MatchOperand_Success;
2917 MipsAsmParser::OperandMatchResultTy
2918 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2919 MCAsmParser &Parser = getParser();
2920 DEBUG(dbgs() << "parseJumpTarget\n");
2922 SMLoc S = getLexer().getLoc();
2924 // Integers and expressions are acceptable
2925 OperandMatchResultTy ResTy = parseImm(Operands);
2926 if (ResTy != MatchOperand_NoMatch)
2929 // Registers are a valid target and have priority over symbols.
2930 ResTy = parseAnyRegister(Operands);
2931 if (ResTy != MatchOperand_NoMatch)
2934 const MCExpr *Expr = nullptr;
2935 if (Parser.parseExpression(Expr)) {
2936 // We have no way of knowing if a symbol was consumed so we must ParseFail
2937 return MatchOperand_ParseFail;
2940 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2941 return MatchOperand_Success;
2944 MipsAsmParser::OperandMatchResultTy
2945 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2946 MCAsmParser &Parser = getParser();
2947 const MCExpr *IdVal;
2948 // If the first token is '$' we may have register operand.
2949 if (Parser.getTok().is(AsmToken::Dollar))
2950 return MatchOperand_NoMatch;
2951 SMLoc S = Parser.getTok().getLoc();
2952 if (getParser().parseExpression(IdVal))
2953 return MatchOperand_ParseFail;
2954 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2955 assert(MCE && "Unexpected MCExpr type.");
2956 int64_t Val = MCE->getValue();
2957 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2958 Operands.push_back(MipsOperand::CreateImm(
2959 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2960 return MatchOperand_Success;
2963 MipsAsmParser::OperandMatchResultTy
2964 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2965 MCAsmParser &Parser = getParser();
2966 switch (getLexer().getKind()) {
2968 return MatchOperand_NoMatch;
2969 case AsmToken::LParen:
2970 case AsmToken::Plus:
2971 case AsmToken::Minus:
2972 case AsmToken::Integer:
2977 SMLoc S = Parser.getTok().getLoc();
2979 if (getParser().parseExpression(Expr))
2980 return MatchOperand_ParseFail;
2983 if (!Expr->EvaluateAsAbsolute(Val)) {
2984 Error(S, "expected immediate value");
2985 return MatchOperand_ParseFail;
2988 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2989 // and because the CPU always adds one to the immediate field, the allowed
2990 // range becomes 1..4. We'll only check the range here and will deal
2991 // with the addition/subtraction when actually decoding/encoding
2993 if (Val < 1 || Val > 4) {
2994 Error(S, "immediate not in range (1..4)");
2995 return MatchOperand_ParseFail;
2999 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3000 return MatchOperand_Success;
3003 MipsAsmParser::OperandMatchResultTy
3004 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3005 MCAsmParser &Parser = getParser();
3006 SmallVector<unsigned, 10> Regs;
3008 unsigned PrevReg = Mips::NoRegister;
3009 bool RegRange = false;
3010 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3012 if (Parser.getTok().isNot(AsmToken::Dollar))
3013 return MatchOperand_ParseFail;
3015 SMLoc S = Parser.getTok().getLoc();
3016 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3017 SMLoc E = getLexer().getLoc();
3018 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3019 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3021 // Remove last register operand because registers from register range
3022 // should be inserted first.
3023 if (RegNo == Mips::RA) {
3024 Regs.push_back(RegNo);
3026 unsigned TmpReg = PrevReg + 1;
3027 while (TmpReg <= RegNo) {
3028 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3029 Error(E, "invalid register operand");
3030 return MatchOperand_ParseFail;
3034 Regs.push_back(TmpReg++);
3040 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3041 (RegNo != Mips::RA)) {
3042 Error(E, "$16 or $31 expected");
3043 return MatchOperand_ParseFail;
3044 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3045 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3046 Error(E, "invalid register operand");
3047 return MatchOperand_ParseFail;
3048 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3049 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3050 Error(E, "consecutive register numbers expected");
3051 return MatchOperand_ParseFail;
3054 Regs.push_back(RegNo);
3057 if (Parser.getTok().is(AsmToken::Minus))
3060 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3061 !Parser.getTok().isNot(AsmToken::Comma)) {
3062 Error(E, "',' or '-' expected");
3063 return MatchOperand_ParseFail;
3066 Lex(); // Consume comma or minus
3067 if (Parser.getTok().isNot(AsmToken::Dollar))
3073 SMLoc E = Parser.getTok().getLoc();
3074 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3075 parseMemOperand(Operands);
3076 return MatchOperand_Success;
3079 MipsAsmParser::OperandMatchResultTy
3080 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3081 MCAsmParser &Parser = getParser();
3083 SMLoc S = Parser.getTok().getLoc();
3084 if (parseAnyRegister(Operands) != MatchOperand_Success)
3085 return MatchOperand_ParseFail;
3087 SMLoc E = Parser.getTok().getLoc();
3088 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3089 unsigned Reg = Op.getGPR32Reg();
3090 Operands.pop_back();
3091 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3092 return MatchOperand_Success;
3095 MipsAsmParser::OperandMatchResultTy
3096 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3097 MCAsmParser &Parser = getParser();
3098 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3099 SmallVector<unsigned, 10> Regs;
3101 if (Parser.getTok().isNot(AsmToken::Dollar))
3102 return MatchOperand_ParseFail;
3104 SMLoc S = Parser.getTok().getLoc();
3106 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3107 return MatchOperand_ParseFail;
3109 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3110 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3111 Regs.push_back(RegNo);
3113 SMLoc E = Parser.getTok().getLoc();
3114 if (Parser.getTok().isNot(AsmToken::Comma)) {
3115 Error(E, "',' expected");
3116 return MatchOperand_ParseFail;
3122 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3123 return MatchOperand_ParseFail;
3125 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3126 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3127 Regs.push_back(RegNo);
3129 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3131 return MatchOperand_Success;
3134 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3136 MCSymbolRefExpr::VariantKind VK =
3137 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3138 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3139 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3140 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3141 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3142 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3143 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3144 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3145 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3146 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3147 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3148 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3149 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3150 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3151 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3152 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3153 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3154 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3155 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3156 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3157 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3158 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3159 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3160 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3161 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3162 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3163 .Default(MCSymbolRefExpr::VK_None);
3165 assert(VK != MCSymbolRefExpr::VK_None);
3170 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3172 /// ::= '(', register, ')'
3173 /// handle it before we iterate so we don't get tripped up by the lack of
3175 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3176 MCAsmParser &Parser = getParser();
3177 if (getLexer().is(AsmToken::LParen)) {
3179 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3181 if (parseOperand(Operands, Name)) {
3182 SMLoc Loc = getLexer().getLoc();
3183 Parser.eatToEndOfStatement();
3184 return Error(Loc, "unexpected token in argument list");
3186 if (Parser.getTok().isNot(AsmToken::RParen)) {
3187 SMLoc Loc = getLexer().getLoc();
3188 Parser.eatToEndOfStatement();
3189 return Error(Loc, "unexpected token, expected ')'");
3192 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3198 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3199 /// either one of these.
3200 /// ::= '[', register, ']'
3201 /// ::= '[', integer, ']'
3202 /// handle it before we iterate so we don't get tripped up by the lack of
3204 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3205 OperandVector &Operands) {
3206 MCAsmParser &Parser = getParser();
3207 if (getLexer().is(AsmToken::LBrac)) {
3209 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3211 if (parseOperand(Operands, Name)) {
3212 SMLoc Loc = getLexer().getLoc();
3213 Parser.eatToEndOfStatement();
3214 return Error(Loc, "unexpected token in argument list");
3216 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3217 SMLoc Loc = getLexer().getLoc();
3218 Parser.eatToEndOfStatement();
3219 return Error(Loc, "unexpected token, expected ']'");
3222 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3228 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3229 SMLoc NameLoc, OperandVector &Operands) {
3230 MCAsmParser &Parser = getParser();
3231 DEBUG(dbgs() << "ParseInstruction\n");
3233 // We have reached first instruction, module directive are now forbidden.
3234 getTargetStreamer().forbidModuleDirective();
3236 // Check if we have valid mnemonic
3237 if (!mnemonicIsValid(Name, 0)) {
3238 Parser.eatToEndOfStatement();
3239 return Error(NameLoc, "unknown instruction");
3241 // First operand in MCInst is instruction mnemonic.
3242 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3244 // Read the remaining operands.
3245 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3246 // Read the first operand.
3247 if (parseOperand(Operands, Name)) {
3248 SMLoc Loc = getLexer().getLoc();
3249 Parser.eatToEndOfStatement();
3250 return Error(Loc, "unexpected token in argument list");
3252 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3254 // AFAIK, parenthesis suffixes are never on the first operand
3256 while (getLexer().is(AsmToken::Comma)) {
3257 Parser.Lex(); // Eat the comma.
3258 // Parse and remember the operand.
3259 if (parseOperand(Operands, Name)) {
3260 SMLoc Loc = getLexer().getLoc();
3261 Parser.eatToEndOfStatement();
3262 return Error(Loc, "unexpected token in argument list");
3264 // Parse bracket and parenthesis suffixes before we iterate
3265 if (getLexer().is(AsmToken::LBrac)) {
3266 if (parseBracketSuffix(Name, Operands))
3268 } else if (getLexer().is(AsmToken::LParen) &&
3269 parseParenSuffix(Name, Operands))
3273 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3274 SMLoc Loc = getLexer().getLoc();
3275 Parser.eatToEndOfStatement();
3276 return Error(Loc, "unexpected token in argument list");
3278 Parser.Lex(); // Consume the EndOfStatement.
3282 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3283 MCAsmParser &Parser = getParser();
3284 SMLoc Loc = getLexer().getLoc();
3285 Parser.eatToEndOfStatement();
3286 return Error(Loc, ErrorMsg);
3289 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3290 return Error(Loc, ErrorMsg);
3293 bool MipsAsmParser::parseSetNoAtDirective() {
3294 MCAsmParser &Parser = getParser();
3295 // Line should look like: ".set noat".
3297 // Set the $at register to $0.
3298 AssemblerOptions.back()->setATRegIndex(0);
3300 Parser.Lex(); // Eat "noat".
3302 // If this is not the end of the statement, report an error.
3303 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3304 reportParseError("unexpected token, expected end of statement");
3308 getTargetStreamer().emitDirectiveSetNoAt();
3309 Parser.Lex(); // Consume the EndOfStatement.
3313 bool MipsAsmParser::parseSetAtDirective() {
3314 // Line can be: ".set at", which sets $at to $1
3315 // or ".set at=$reg", which sets $at to $reg.
3316 MCAsmParser &Parser = getParser();
3317 Parser.Lex(); // Eat "at".
3319 if (getLexer().is(AsmToken::EndOfStatement)) {
3320 // No register was specified, so we set $at to $1.
3321 AssemblerOptions.back()->setATRegIndex(1);
3323 getTargetStreamer().emitDirectiveSetAt();
3324 Parser.Lex(); // Consume the EndOfStatement.
3328 if (getLexer().isNot(AsmToken::Equal)) {
3329 reportParseError("unexpected token, expected equals sign");
3332 Parser.Lex(); // Eat "=".
3334 if (getLexer().isNot(AsmToken::Dollar)) {
3335 if (getLexer().is(AsmToken::EndOfStatement)) {
3336 reportParseError("no register specified");
3339 reportParseError("unexpected token, expected dollar sign '$'");
3343 Parser.Lex(); // Eat "$".
3345 // Find out what "reg" is.
3347 const AsmToken &Reg = Parser.getTok();
3348 if (Reg.is(AsmToken::Identifier)) {
3349 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3350 } else if (Reg.is(AsmToken::Integer)) {
3351 AtRegNo = Reg.getIntVal();
3353 reportParseError("unexpected token, expected identifier or integer");
3357 // Check if $reg is a valid register. If it is, set $at to $reg.
3358 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3359 reportParseError("invalid register");
3362 Parser.Lex(); // Eat "reg".
3364 // If this is not the end of the statement, report an error.
3365 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3366 reportParseError("unexpected token, expected end of statement");
3370 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3372 Parser.Lex(); // Consume the EndOfStatement.
3376 bool MipsAsmParser::parseSetReorderDirective() {
3377 MCAsmParser &Parser = getParser();
3379 // If this is not the end of the statement, report an error.
3380 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3381 reportParseError("unexpected token, expected end of statement");
3384 AssemblerOptions.back()->setReorder();
3385 getTargetStreamer().emitDirectiveSetReorder();
3386 Parser.Lex(); // Consume the EndOfStatement.
3390 bool MipsAsmParser::parseSetNoReorderDirective() {
3391 MCAsmParser &Parser = getParser();
3393 // If this is not the end of the statement, report an error.
3394 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3395 reportParseError("unexpected token, expected end of statement");
3398 AssemblerOptions.back()->setNoReorder();
3399 getTargetStreamer().emitDirectiveSetNoReorder();
3400 Parser.Lex(); // Consume the EndOfStatement.
3404 bool MipsAsmParser::parseSetMacroDirective() {
3405 MCAsmParser &Parser = getParser();
3407 // If this is not the end of the statement, report an error.
3408 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3409 reportParseError("unexpected token, expected end of statement");
3412 AssemblerOptions.back()->setMacro();
3413 Parser.Lex(); // Consume the EndOfStatement.
3417 bool MipsAsmParser::parseSetNoMacroDirective() {
3418 MCAsmParser &Parser = getParser();
3420 // If this is not the end of the statement, report an error.
3421 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3422 reportParseError("unexpected token, expected end of statement");
3425 if (AssemblerOptions.back()->isReorder()) {
3426 reportParseError("`noreorder' must be set before `nomacro'");
3429 AssemblerOptions.back()->setNoMacro();
3430 Parser.Lex(); // Consume the EndOfStatement.
3434 bool MipsAsmParser::parseSetMsaDirective() {
3435 MCAsmParser &Parser = getParser();
3438 // If this is not the end of the statement, report an error.
3439 if (getLexer().isNot(AsmToken::EndOfStatement))
3440 return reportParseError("unexpected token, expected end of statement");
3442 setFeatureBits(Mips::FeatureMSA, "msa");
3443 getTargetStreamer().emitDirectiveSetMsa();
3447 bool MipsAsmParser::parseSetNoMsaDirective() {
3448 MCAsmParser &Parser = getParser();
3451 // If this is not the end of the statement, report an error.
3452 if (getLexer().isNot(AsmToken::EndOfStatement))
3453 return reportParseError("unexpected token, expected end of statement");
3455 clearFeatureBits(Mips::FeatureMSA, "msa");
3456 getTargetStreamer().emitDirectiveSetNoMsa();
3460 bool MipsAsmParser::parseSetNoDspDirective() {
3461 MCAsmParser &Parser = getParser();
3462 Parser.Lex(); // Eat "nodsp".
3464 // If this is not the end of the statement, report an error.
3465 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3466 reportParseError("unexpected token, expected end of statement");
3470 clearFeatureBits(Mips::FeatureDSP, "dsp");
3471 getTargetStreamer().emitDirectiveSetNoDsp();
3475 bool MipsAsmParser::parseSetMips16Directive() {
3476 MCAsmParser &Parser = getParser();
3477 Parser.Lex(); // Eat "mips16".
3479 // If this is not the end of the statement, report an error.
3480 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3481 reportParseError("unexpected token, expected end of statement");
3485 setFeatureBits(Mips::FeatureMips16, "mips16");
3486 getTargetStreamer().emitDirectiveSetMips16();
3487 Parser.Lex(); // Consume the EndOfStatement.
3491 bool MipsAsmParser::parseSetNoMips16Directive() {
3492 MCAsmParser &Parser = getParser();
3493 Parser.Lex(); // Eat "nomips16".
3495 // If this is not the end of the statement, report an error.
3496 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3497 reportParseError("unexpected token, expected end of statement");
3501 clearFeatureBits(Mips::FeatureMips16, "mips16");
3502 getTargetStreamer().emitDirectiveSetNoMips16();
3503 Parser.Lex(); // Consume the EndOfStatement.
3507 bool MipsAsmParser::parseSetFpDirective() {
3508 MCAsmParser &Parser = getParser();
3509 MipsABIFlagsSection::FpABIKind FpAbiVal;
3510 // Line can be: .set fp=32
3513 Parser.Lex(); // Eat fp token
3514 AsmToken Tok = Parser.getTok();
3515 if (Tok.isNot(AsmToken::Equal)) {
3516 reportParseError("unexpected token, expected equals sign '='");
3519 Parser.Lex(); // Eat '=' token.
3520 Tok = Parser.getTok();
3522 if (!parseFpABIValue(FpAbiVal, ".set"))
3525 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3526 reportParseError("unexpected token, expected end of statement");
3529 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3530 Parser.Lex(); // Consume the EndOfStatement.
3534 bool MipsAsmParser::parseSetPopDirective() {
3535 MCAsmParser &Parser = getParser();
3536 SMLoc Loc = getLexer().getLoc();
3539 if (getLexer().isNot(AsmToken::EndOfStatement))
3540 return reportParseError("unexpected token, expected end of statement");
3542 // Always keep an element on the options "stack" to prevent the user
3543 // from changing the initial options. This is how we remember them.
3544 if (AssemblerOptions.size() == 2)
3545 return reportParseError(Loc, ".set pop with no .set push");
3547 AssemblerOptions.pop_back();
3548 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3550 getTargetStreamer().emitDirectiveSetPop();
3554 bool MipsAsmParser::parseSetPushDirective() {
3555 MCAsmParser &Parser = getParser();
3557 if (getLexer().isNot(AsmToken::EndOfStatement))
3558 return reportParseError("unexpected token, expected end of statement");
3560 // Create a copy of the current assembler options environment and push it.
3561 AssemblerOptions.push_back(
3562 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3564 getTargetStreamer().emitDirectiveSetPush();
3568 bool MipsAsmParser::parseSetAssignment() {
3570 const MCExpr *Value;
3571 MCAsmParser &Parser = getParser();
3573 if (Parser.parseIdentifier(Name))
3574 reportParseError("expected identifier after .set");
3576 if (getLexer().isNot(AsmToken::Comma))
3577 return reportParseError("unexpected token, expected comma");
3580 if (Parser.parseExpression(Value))
3581 return reportParseError("expected valid expression after comma");
3583 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3584 Sym->setVariableValue(Value);
3589 bool MipsAsmParser::parseSetMips0Directive() {
3590 MCAsmParser &Parser = getParser();
3592 if (getLexer().isNot(AsmToken::EndOfStatement))
3593 return reportParseError("unexpected token, expected end of statement");
3595 // Reset assembler options to their initial values.
3596 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3597 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3599 getTargetStreamer().emitDirectiveSetMips0();
3603 bool MipsAsmParser::parseSetArchDirective() {
3604 MCAsmParser &Parser = getParser();
3606 if (getLexer().isNot(AsmToken::Equal))
3607 return reportParseError("unexpected token, expected equals sign");
3611 if (Parser.parseIdentifier(Arch))
3612 return reportParseError("expected arch identifier");
3614 StringRef ArchFeatureName =
3615 StringSwitch<StringRef>(Arch)
3616 .Case("mips1", "mips1")
3617 .Case("mips2", "mips2")
3618 .Case("mips3", "mips3")
3619 .Case("mips4", "mips4")
3620 .Case("mips5", "mips5")
3621 .Case("mips32", "mips32")
3622 .Case("mips32r2", "mips32r2")
3623 .Case("mips32r3", "mips32r3")
3624 .Case("mips32r5", "mips32r5")
3625 .Case("mips32r6", "mips32r6")
3626 .Case("mips64", "mips64")
3627 .Case("mips64r2", "mips64r2")
3628 .Case("mips64r3", "mips64r3")
3629 .Case("mips64r5", "mips64r5")
3630 .Case("mips64r6", "mips64r6")
3631 .Case("cnmips", "cnmips")
3632 .Case("r4000", "mips3") // This is an implementation of Mips3.
3635 if (ArchFeatureName.empty())
3636 return reportParseError("unsupported architecture");
3638 selectArch(ArchFeatureName);
3639 getTargetStreamer().emitDirectiveSetArch(Arch);
3643 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3644 MCAsmParser &Parser = getParser();
3646 if (getLexer().isNot(AsmToken::EndOfStatement))
3647 return reportParseError("unexpected token, expected end of statement");
3651 llvm_unreachable("Unimplemented feature");
3652 case Mips::FeatureDSP:
3653 setFeatureBits(Mips::FeatureDSP, "dsp");
3654 getTargetStreamer().emitDirectiveSetDsp();
3656 case Mips::FeatureMicroMips:
3657 getTargetStreamer().emitDirectiveSetMicroMips();
3659 case Mips::FeatureMips1:
3660 selectArch("mips1");
3661 getTargetStreamer().emitDirectiveSetMips1();
3663 case Mips::FeatureMips2:
3664 selectArch("mips2");
3665 getTargetStreamer().emitDirectiveSetMips2();
3667 case Mips::FeatureMips3:
3668 selectArch("mips3");
3669 getTargetStreamer().emitDirectiveSetMips3();
3671 case Mips::FeatureMips4:
3672 selectArch("mips4");
3673 getTargetStreamer().emitDirectiveSetMips4();
3675 case Mips::FeatureMips5:
3676 selectArch("mips5");
3677 getTargetStreamer().emitDirectiveSetMips5();
3679 case Mips::FeatureMips32:
3680 selectArch("mips32");
3681 getTargetStreamer().emitDirectiveSetMips32();
3683 case Mips::FeatureMips32r2:
3684 selectArch("mips32r2");
3685 getTargetStreamer().emitDirectiveSetMips32R2();
3687 case Mips::FeatureMips32r3:
3688 selectArch("mips32r3");
3689 getTargetStreamer().emitDirectiveSetMips32R3();
3691 case Mips::FeatureMips32r5:
3692 selectArch("mips32r5");
3693 getTargetStreamer().emitDirectiveSetMips32R5();
3695 case Mips::FeatureMips32r6:
3696 selectArch("mips32r6");
3697 getTargetStreamer().emitDirectiveSetMips32R6();
3699 case Mips::FeatureMips64:
3700 selectArch("mips64");
3701 getTargetStreamer().emitDirectiveSetMips64();
3703 case Mips::FeatureMips64r2:
3704 selectArch("mips64r2");
3705 getTargetStreamer().emitDirectiveSetMips64R2();
3707 case Mips::FeatureMips64r3:
3708 selectArch("mips64r3");
3709 getTargetStreamer().emitDirectiveSetMips64R3();
3711 case Mips::FeatureMips64r5:
3712 selectArch("mips64r5");
3713 getTargetStreamer().emitDirectiveSetMips64R5();
3715 case Mips::FeatureMips64r6:
3716 selectArch("mips64r6");
3717 getTargetStreamer().emitDirectiveSetMips64R6();
3723 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3724 MCAsmParser &Parser = getParser();
3725 if (getLexer().isNot(AsmToken::Comma)) {
3726 SMLoc Loc = getLexer().getLoc();
3727 Parser.eatToEndOfStatement();
3728 return Error(Loc, ErrorStr);
3731 Parser.Lex(); // Eat the comma.
3735 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3736 if (AssemblerOptions.back()->isReorder())
3737 Warning(Loc, ".cpload should be inside a noreorder section");
3739 if (inMips16Mode()) {
3740 reportParseError(".cpload is not supported in Mips16 mode");
3744 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3745 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3746 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3747 reportParseError("expected register containing function address");
3751 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3752 if (!RegOpnd.isGPRAsmReg()) {
3753 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3757 // If this is not the end of the statement, report an error.
3758 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3759 reportParseError("unexpected token, expected end of statement");
3763 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3767 bool MipsAsmParser::parseDirectiveCPSetup() {
3768 MCAsmParser &Parser = getParser();
3771 bool SaveIsReg = true;
3773 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3774 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3775 if (ResTy == MatchOperand_NoMatch) {
3776 reportParseError("expected register containing function address");
3777 Parser.eatToEndOfStatement();
3781 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3782 if (!FuncRegOpnd.isGPRAsmReg()) {
3783 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3784 Parser.eatToEndOfStatement();
3788 FuncReg = FuncRegOpnd.getGPR32Reg();
3791 if (!eatComma("unexpected token, expected comma"))
3794 ResTy = parseAnyRegister(TmpReg);
3795 if (ResTy == MatchOperand_NoMatch) {
3796 const AsmToken &Tok = Parser.getTok();
3797 if (Tok.is(AsmToken::Integer)) {
3798 Save = Tok.getIntVal();
3802 reportParseError("expected save register or stack offset");
3803 Parser.eatToEndOfStatement();
3807 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3808 if (!SaveOpnd.isGPRAsmReg()) {
3809 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3810 Parser.eatToEndOfStatement();
3813 Save = SaveOpnd.getGPR32Reg();
3816 if (!eatComma("unexpected token, expected comma"))
3820 if (Parser.parseExpression(Expr)) {
3821 reportParseError("expected expression");
3825 if (Expr->getKind() != MCExpr::SymbolRef) {
3826 reportParseError("expected symbol");
3829 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3831 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3836 bool MipsAsmParser::parseDirectiveNaN() {
3837 MCAsmParser &Parser = getParser();
3838 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3839 const AsmToken &Tok = Parser.getTok();
3841 if (Tok.getString() == "2008") {
3843 getTargetStreamer().emitDirectiveNaN2008();
3845 } else if (Tok.getString() == "legacy") {
3847 getTargetStreamer().emitDirectiveNaNLegacy();
3851 // If we don't recognize the option passed to the .nan
3852 // directive (e.g. no option or unknown option), emit an error.
3853 reportParseError("invalid option in .nan directive");
3857 bool MipsAsmParser::parseDirectiveSet() {
3858 MCAsmParser &Parser = getParser();
3859 // Get the next token.
3860 const AsmToken &Tok = Parser.getTok();
3862 if (Tok.getString() == "noat") {
3863 return parseSetNoAtDirective();
3864 } else if (Tok.getString() == "at") {
3865 return parseSetAtDirective();
3866 } else if (Tok.getString() == "arch") {
3867 return parseSetArchDirective();
3868 } else if (Tok.getString() == "fp") {
3869 return parseSetFpDirective();
3870 } else if (Tok.getString() == "pop") {
3871 return parseSetPopDirective();
3872 } else if (Tok.getString() == "push") {
3873 return parseSetPushDirective();
3874 } else if (Tok.getString() == "reorder") {
3875 return parseSetReorderDirective();
3876 } else if (Tok.getString() == "noreorder") {
3877 return parseSetNoReorderDirective();
3878 } else if (Tok.getString() == "macro") {
3879 return parseSetMacroDirective();
3880 } else if (Tok.getString() == "nomacro") {
3881 return parseSetNoMacroDirective();
3882 } else if (Tok.getString() == "mips16") {
3883 return parseSetMips16Directive();
3884 } else if (Tok.getString() == "nomips16") {
3885 return parseSetNoMips16Directive();
3886 } else if (Tok.getString() == "nomicromips") {
3887 getTargetStreamer().emitDirectiveSetNoMicroMips();
3888 Parser.eatToEndOfStatement();
3890 } else if (Tok.getString() == "micromips") {
3891 return parseSetFeature(Mips::FeatureMicroMips);
3892 } else if (Tok.getString() == "mips0") {
3893 return parseSetMips0Directive();
3894 } else if (Tok.getString() == "mips1") {
3895 return parseSetFeature(Mips::FeatureMips1);
3896 } else if (Tok.getString() == "mips2") {
3897 return parseSetFeature(Mips::FeatureMips2);
3898 } else if (Tok.getString() == "mips3") {
3899 return parseSetFeature(Mips::FeatureMips3);
3900 } else if (Tok.getString() == "mips4") {
3901 return parseSetFeature(Mips::FeatureMips4);
3902 } else if (Tok.getString() == "mips5") {
3903 return parseSetFeature(Mips::FeatureMips5);
3904 } else if (Tok.getString() == "mips32") {
3905 return parseSetFeature(Mips::FeatureMips32);
3906 } else if (Tok.getString() == "mips32r2") {
3907 return parseSetFeature(Mips::FeatureMips32r2);
3908 } else if (Tok.getString() == "mips32r3") {
3909 return parseSetFeature(Mips::FeatureMips32r3);
3910 } else if (Tok.getString() == "mips32r5") {
3911 return parseSetFeature(Mips::FeatureMips32r5);
3912 } else if (Tok.getString() == "mips32r6") {
3913 return parseSetFeature(Mips::FeatureMips32r6);
3914 } else if (Tok.getString() == "mips64") {
3915 return parseSetFeature(Mips::FeatureMips64);
3916 } else if (Tok.getString() == "mips64r2") {
3917 return parseSetFeature(Mips::FeatureMips64r2);
3918 } else if (Tok.getString() == "mips64r3") {
3919 return parseSetFeature(Mips::FeatureMips64r3);
3920 } else if (Tok.getString() == "mips64r5") {
3921 return parseSetFeature(Mips::FeatureMips64r5);
3922 } else if (Tok.getString() == "mips64r6") {
3923 return parseSetFeature(Mips::FeatureMips64r6);
3924 } else if (Tok.getString() == "dsp") {
3925 return parseSetFeature(Mips::FeatureDSP);
3926 } else if (Tok.getString() == "nodsp") {
3927 return parseSetNoDspDirective();
3928 } else if (Tok.getString() == "msa") {
3929 return parseSetMsaDirective();
3930 } else if (Tok.getString() == "nomsa") {
3931 return parseSetNoMsaDirective();
3933 // It is just an identifier, look for an assignment.
3934 parseSetAssignment();
3941 /// parseDataDirective
3942 /// ::= .word [ expression (, expression)* ]
3943 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3944 MCAsmParser &Parser = getParser();
3945 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3947 const MCExpr *Value;
3948 if (getParser().parseExpression(Value))
3951 getParser().getStreamer().EmitValue(Value, Size);
3953 if (getLexer().is(AsmToken::EndOfStatement))
3956 if (getLexer().isNot(AsmToken::Comma))
3957 return Error(L, "unexpected token, expected comma");
3966 /// parseDirectiveGpWord
3967 /// ::= .gpword local_sym
3968 bool MipsAsmParser::parseDirectiveGpWord() {
3969 MCAsmParser &Parser = getParser();
3970 const MCExpr *Value;
3971 // EmitGPRel32Value requires an expression, so we are using base class
3972 // method to evaluate the expression.
3973 if (getParser().parseExpression(Value))
3975 getParser().getStreamer().EmitGPRel32Value(Value);
3977 if (getLexer().isNot(AsmToken::EndOfStatement))
3978 return Error(getLexer().getLoc(),
3979 "unexpected token, expected end of statement");
3980 Parser.Lex(); // Eat EndOfStatement token.
3984 /// parseDirectiveGpDWord
3985 /// ::= .gpdword local_sym
3986 bool MipsAsmParser::parseDirectiveGpDWord() {
3987 MCAsmParser &Parser = getParser();
3988 const MCExpr *Value;
3989 // EmitGPRel64Value requires an expression, so we are using base class
3990 // method to evaluate the expression.
3991 if (getParser().parseExpression(Value))
3993 getParser().getStreamer().EmitGPRel64Value(Value);
3995 if (getLexer().isNot(AsmToken::EndOfStatement))
3996 return Error(getLexer().getLoc(),
3997 "unexpected token, expected end of statement");
3998 Parser.Lex(); // Eat EndOfStatement token.
4002 bool MipsAsmParser::parseDirectiveOption() {
4003 MCAsmParser &Parser = getParser();
4004 // Get the option token.
4005 AsmToken Tok = Parser.getTok();
4006 // At the moment only identifiers are supported.
4007 if (Tok.isNot(AsmToken::Identifier)) {
4008 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4009 Parser.eatToEndOfStatement();
4013 StringRef Option = Tok.getIdentifier();
4015 if (Option == "pic0") {
4016 getTargetStreamer().emitDirectiveOptionPic0();
4018 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4019 Error(Parser.getTok().getLoc(),
4020 "unexpected token, expected end of statement");
4021 Parser.eatToEndOfStatement();
4026 if (Option == "pic2") {
4027 getTargetStreamer().emitDirectiveOptionPic2();
4029 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4030 Error(Parser.getTok().getLoc(),
4031 "unexpected token, expected end of statement");
4032 Parser.eatToEndOfStatement();
4038 Warning(Parser.getTok().getLoc(),
4039 "unknown option, expected 'pic0' or 'pic2'");
4040 Parser.eatToEndOfStatement();
4044 /// parseInsnDirective
4046 bool MipsAsmParser::parseInsnDirective() {
4047 // If this is not the end of the statement, report an error.
4048 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4049 reportParseError("unexpected token, expected end of statement");
4053 // The actual label marking happens in
4054 // MipsELFStreamer::createPendingLabelRelocs().
4055 getTargetStreamer().emitDirectiveInsn();
4057 getParser().Lex(); // Eat EndOfStatement token.
4061 /// parseDirectiveModule
4062 /// ::= .module oddspreg
4063 /// ::= .module nooddspreg
4064 /// ::= .module fp=value
4065 bool MipsAsmParser::parseDirectiveModule() {
4066 MCAsmParser &Parser = getParser();
4067 MCAsmLexer &Lexer = getLexer();
4068 SMLoc L = Lexer.getLoc();
4070 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4071 // TODO : get a better message.
4072 reportParseError(".module directive must appear before any code");
4077 if (Parser.parseIdentifier(Option)) {
4078 reportParseError("expected .module option identifier");
4082 if (Option == "oddspreg") {
4083 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4084 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4086 // If this is not the end of the statement, report an error.
4087 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4088 reportParseError("unexpected token, expected end of statement");
4092 return false; // parseDirectiveModule has finished successfully.
4093 } else if (Option == "nooddspreg") {
4095 Error(L, "'.module nooddspreg' requires the O32 ABI");
4099 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4100 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4102 // If this is not the end of the statement, report an error.
4103 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4104 reportParseError("unexpected token, expected end of statement");
4108 return false; // parseDirectiveModule has finished successfully.
4109 } else if (Option == "fp") {
4110 return parseDirectiveModuleFP();
4112 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4116 /// parseDirectiveModuleFP
4120 bool MipsAsmParser::parseDirectiveModuleFP() {
4121 MCAsmParser &Parser = getParser();
4122 MCAsmLexer &Lexer = getLexer();
4124 if (Lexer.isNot(AsmToken::Equal)) {
4125 reportParseError("unexpected token, expected equals sign '='");
4128 Parser.Lex(); // Eat '=' token.
4130 MipsABIFlagsSection::FpABIKind FpABI;
4131 if (!parseFpABIValue(FpABI, ".module"))
4134 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4135 reportParseError("unexpected token, expected end of statement");
4139 // Emit appropriate flags.
4140 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4141 Parser.Lex(); // Consume the EndOfStatement.
4145 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4146 StringRef Directive) {
4147 MCAsmParser &Parser = getParser();
4148 MCAsmLexer &Lexer = getLexer();
4150 if (Lexer.is(AsmToken::Identifier)) {
4151 StringRef Value = Parser.getTok().getString();
4154 if (Value != "xx") {
4155 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4160 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4164 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4168 if (Lexer.is(AsmToken::Integer)) {
4169 unsigned Value = Parser.getTok().getIntVal();
4172 if (Value != 32 && Value != 64) {
4173 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4179 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4183 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4185 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4193 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4194 MCAsmParser &Parser = getParser();
4195 StringRef IDVal = DirectiveID.getString();
4197 if (IDVal == ".cpload")
4198 return parseDirectiveCpLoad(DirectiveID.getLoc());
4199 if (IDVal == ".dword") {
4200 parseDataDirective(8, DirectiveID.getLoc());
4203 if (IDVal == ".ent") {
4204 StringRef SymbolName;
4206 if (Parser.parseIdentifier(SymbolName)) {
4207 reportParseError("expected identifier after .ent");
4211 // There's an undocumented extension that allows an integer to
4212 // follow the name of the procedure which AFAICS is ignored by GAS.
4213 // Example: .ent foo,2
4214 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4215 if (getLexer().isNot(AsmToken::Comma)) {
4216 // Even though we accept this undocumented extension for compatibility
4217 // reasons, the additional integer argument does not actually change
4218 // the behaviour of the '.ent' directive, so we would like to discourage
4219 // its use. We do this by not referring to the extended version in
4220 // error messages which are not directly related to its use.
4221 reportParseError("unexpected token, expected end of statement");
4224 Parser.Lex(); // Eat the comma.
4225 const MCExpr *DummyNumber;
4226 int64_t DummyNumberVal;
4227 // If the user was explicitly trying to use the extended version,
4228 // we still give helpful extension-related error messages.
4229 if (Parser.parseExpression(DummyNumber)) {
4230 reportParseError("expected number after comma");
4233 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4234 reportParseError("expected an absolute expression after comma");
4239 // If this is not the end of the statement, report an error.
4240 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4241 reportParseError("unexpected token, expected end of statement");
4245 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4247 getTargetStreamer().emitDirectiveEnt(*Sym);
4252 if (IDVal == ".end") {
4253 StringRef SymbolName;
4255 if (Parser.parseIdentifier(SymbolName)) {
4256 reportParseError("expected identifier after .end");
4260 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4261 reportParseError("unexpected token, expected end of statement");
4265 if (CurrentFn == nullptr) {
4266 reportParseError(".end used without .ent");
4270 if ((SymbolName != CurrentFn->getName())) {
4271 reportParseError(".end symbol does not match .ent symbol");
4275 getTargetStreamer().emitDirectiveEnd(SymbolName);
4276 CurrentFn = nullptr;
4280 if (IDVal == ".frame") {
4281 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4282 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4283 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4284 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4285 reportParseError("expected stack register");
4289 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4290 if (!StackRegOpnd.isGPRAsmReg()) {
4291 reportParseError(StackRegOpnd.getStartLoc(),
4292 "expected general purpose register");
4295 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4297 if (Parser.getTok().is(AsmToken::Comma))
4300 reportParseError("unexpected token, expected comma");
4304 // Parse the frame size.
4305 const MCExpr *FrameSize;
4306 int64_t FrameSizeVal;
4308 if (Parser.parseExpression(FrameSize)) {
4309 reportParseError("expected frame size value");
4313 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4314 reportParseError("frame size not an absolute expression");
4318 if (Parser.getTok().is(AsmToken::Comma))
4321 reportParseError("unexpected token, expected comma");
4325 // Parse the return register.
4327 ResTy = parseAnyRegister(TmpReg);
4328 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4329 reportParseError("expected return register");
4333 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4334 if (!ReturnRegOpnd.isGPRAsmReg()) {
4335 reportParseError(ReturnRegOpnd.getStartLoc(),
4336 "expected general purpose register");
4340 // If this is not the end of the statement, report an error.
4341 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4342 reportParseError("unexpected token, expected end of statement");
4346 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4347 ReturnRegOpnd.getGPR32Reg());
4351 if (IDVal == ".set") {
4352 return parseDirectiveSet();
4355 if (IDVal == ".mask" || IDVal == ".fmask") {
4356 // .mask bitmask, frame_offset
4357 // bitmask: One bit for each register used.
4358 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4359 // first register is expected to be saved.
4361 // .mask 0x80000000, -4
4362 // .fmask 0x80000000, -4
4365 // Parse the bitmask
4366 const MCExpr *BitMask;
4369 if (Parser.parseExpression(BitMask)) {
4370 reportParseError("expected bitmask value");
4374 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4375 reportParseError("bitmask not an absolute expression");
4379 if (Parser.getTok().is(AsmToken::Comma))
4382 reportParseError("unexpected token, expected comma");
4386 // Parse the frame_offset
4387 const MCExpr *FrameOffset;
4388 int64_t FrameOffsetVal;
4390 if (Parser.parseExpression(FrameOffset)) {
4391 reportParseError("expected frame offset value");
4395 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4396 reportParseError("frame offset not an absolute expression");
4400 // If this is not the end of the statement, report an error.
4401 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4402 reportParseError("unexpected token, expected end of statement");
4406 if (IDVal == ".mask")
4407 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4409 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4413 if (IDVal == ".nan")
4414 return parseDirectiveNaN();
4416 if (IDVal == ".gpword") {
4417 parseDirectiveGpWord();
4421 if (IDVal == ".gpdword") {
4422 parseDirectiveGpDWord();
4426 if (IDVal == ".word") {
4427 parseDataDirective(4, DirectiveID.getLoc());
4431 if (IDVal == ".option")
4432 return parseDirectiveOption();
4434 if (IDVal == ".abicalls") {
4435 getTargetStreamer().emitDirectiveAbiCalls();
4436 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4437 Error(Parser.getTok().getLoc(),
4438 "unexpected token, expected end of statement");
4440 Parser.eatToEndOfStatement();
4445 if (IDVal == ".cpsetup")
4446 return parseDirectiveCPSetup();
4448 if (IDVal == ".module")
4449 return parseDirectiveModule();
4451 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4452 return parseInternalDirectiveReallowModule();
4454 if (IDVal == ".insn")
4455 return parseInsnDirective();
4460 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4461 // If this is not the end of the statement, report an error.
4462 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4463 reportParseError("unexpected token, expected end of statement");
4467 getTargetStreamer().reallowModuleDirective();
4469 getParser().Lex(); // Eat EndOfStatement token.
4473 extern "C" void LLVMInitializeMipsAsmParser() {
4474 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4475 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4476 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4477 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4480 #define GET_REGISTER_MATCHER
4481 #define GET_MATCHER_IMPLEMENTATION
4482 #include "MipsGenAsmMatcher.inc"