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, bool Is32BitImm, 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, true, IDLoc, Instructions);
1613 case Mips::LoadImm64:
1614 return expandLoadImm(Inst, false, IDLoc, Instructions);
1615 case Mips::LoadAddrImm32:
1616 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1617 case Mips::LoadAddrReg32:
1618 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1619 case Mips::B_MM_Pseudo:
1620 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1623 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1624 case Mips::JalOneReg:
1625 case Mips::JalTwoReg:
1626 return expandJalWithRegs(Inst, IDLoc, Instructions);
1631 template <unsigned ShiftAmount>
1632 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1633 SmallVectorImpl<MCInst> &Instructions) {
1635 if (ShiftAmount >= 32) {
1636 tmpInst.setOpcode(Mips::DSLL32);
1637 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1638 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1639 tmpInst.addOperand(MCOperand::CreateImm(ShiftAmount - 32));
1640 tmpInst.setLoc(IDLoc);
1641 Instructions.push_back(tmpInst);
1643 } else if (ShiftAmount > 0) {
1644 tmpInst.setOpcode(Mips::DSLL);
1645 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1646 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1647 tmpInst.addOperand(MCOperand::CreateImm(ShiftAmount));
1648 tmpInst.setLoc(IDLoc);
1649 Instructions.push_back(tmpInst);
1652 // There's no need for an ORi if the immediate is 0.
1653 if (Operand.isImm() && Operand.getImm() == 0)
1656 tmpInst.setOpcode(Mips::ORi);
1657 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1658 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1659 tmpInst.addOperand(Operand);
1660 tmpInst.setLoc(IDLoc);
1661 Instructions.push_back(tmpInst);
1664 template <unsigned ShiftAmount>
1665 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1666 SmallVectorImpl<MCInst> &Instructions) {
1667 createLShiftOri<ShiftAmount>(MCOperand::CreateImm(Value), RegNo, IDLoc,
1672 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1673 SmallVectorImpl<MCInst> &Instructions) {
1674 // Create a JALR instruction which is going to replace the pseudo-JAL.
1676 JalrInst.setLoc(IDLoc);
1677 const MCOperand FirstRegOp = Inst.getOperand(0);
1678 const unsigned Opcode = Inst.getOpcode();
1680 if (Opcode == Mips::JalOneReg) {
1681 // jal $rs => jalr $rs
1682 if (inMicroMipsMode()) {
1683 JalrInst.setOpcode(Mips::JALR16_MM);
1684 JalrInst.addOperand(FirstRegOp);
1686 JalrInst.setOpcode(Mips::JALR);
1687 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1688 JalrInst.addOperand(FirstRegOp);
1690 } else if (Opcode == Mips::JalTwoReg) {
1691 // jal $rd, $rs => jalr $rd, $rs
1692 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1693 JalrInst.addOperand(FirstRegOp);
1694 const MCOperand SecondRegOp = Inst.getOperand(1);
1695 JalrInst.addOperand(SecondRegOp);
1697 Instructions.push_back(JalrInst);
1699 // If .set reorder is active, emit a NOP after it.
1700 if (AssemblerOptions.back()->isReorder()) {
1701 // This is a 32-bit NOP because these 2 pseudo-instructions
1702 // do not have a short delay slot.
1704 NopInst.setOpcode(Mips::SLL);
1705 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1706 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1707 NopInst.addOperand(MCOperand::CreateImm(0));
1708 Instructions.push_back(NopInst);
1714 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1715 SmallVectorImpl<MCInst> &Instructions) {
1716 if (!Is32BitImm && !isGP64bit()) {
1717 Error(IDLoc, "instruction requires a 64-bit architecture");
1722 const MCOperand &ImmOp = Inst.getOperand(1);
1723 assert(ImmOp.isImm() && "expected immediate operand kind");
1724 const MCOperand &RegOp = Inst.getOperand(0);
1725 assert(RegOp.isReg() && "expected register operand kind");
1727 int64_t ImmValue = ImmOp.getImm();
1728 unsigned Reg = RegOp.getReg();
1729 tmpInst.setLoc(IDLoc);
1730 // FIXME: gas has a special case for values that are 000...1111, which
1731 // becomes a li -1 and then a dsrl
1732 if (0 <= ImmValue && ImmValue <= 65535) {
1733 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1734 // li d,j => ori d,$zero,j
1735 tmpInst.setOpcode(Mips::ORi);
1736 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1737 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1738 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1739 Instructions.push_back(tmpInst);
1740 } else if (ImmValue < 0 && ImmValue >= -32768) {
1741 // For negative signed 16-bit values (-32768 <= j < 0):
1742 // li d,j => addiu d,$zero,j
1743 tmpInst.setOpcode(Mips::ADDiu);
1744 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1745 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1746 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1747 Instructions.push_back(tmpInst);
1748 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1749 // For all other values which are representable as a 32-bit integer:
1750 // li d,j => lui d,hi16(j)
1752 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1753 uint16_t Bits15To0 = ImmValue & 0xffff;
1755 tmpInst.setOpcode(Mips::LUi);
1756 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1757 tmpInst.addOperand(MCOperand::CreateImm(Bits31To16));
1758 Instructions.push_back(tmpInst);
1759 createLShiftOri<0>(Bits15To0, Reg, IDLoc, Instructions);
1760 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1762 Error(IDLoc, "instruction requires a 32-bit immediate");
1766 // <------- lo32 ------>
1767 // <------- hi32 ------>
1768 // <- hi16 -> <- lo16 ->
1769 // _________________________________
1771 // | 16-bits | 16-bits | 16-bits |
1772 // |__________|__________|__________|
1774 // For any 64-bit value that is representable as a 48-bit integer:
1775 // li d,j => lui d,hi16(j)
1776 // ori d,d,hi16(lo32(j))
1778 // ori d,d,lo16(lo32(j))
1779 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1780 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1781 uint16_t Bits15To0 = ImmValue & 0xffff;
1783 tmpInst.setOpcode(Mips::LUi);
1784 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1785 tmpInst.addOperand(MCOperand::CreateImm(Bits47To32));
1786 Instructions.push_back(tmpInst);
1787 createLShiftOri<0>(Bits31To16, Reg, IDLoc, Instructions);
1788 createLShiftOri<16>(Bits15To0, Reg, IDLoc, Instructions);
1791 Error(IDLoc, "instruction requires a 32-bit immediate");
1795 // <------- hi32 ------> <------- lo32 ------>
1796 // <- hi16 -> <- lo16 ->
1797 // ___________________________________________
1799 // | 16-bits | 16-bits | 16-bits | 16-bits |
1800 // |__________|__________|__________|__________|
1802 // For all other values which are representable as a 64-bit integer:
1803 // li d,j => lui d,hi16(j)
1804 // ori d,d,lo16(hi32(j))
1806 // ori d,d,hi16(lo32(j))
1808 // ori d,d,lo16(lo32(j))
1809 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1810 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1811 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1812 uint16_t Bits15To0 = ImmValue & 0xffff;
1814 tmpInst.setOpcode(Mips::LUi);
1815 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1816 tmpInst.addOperand(MCOperand::CreateImm(Bits63To48));
1817 Instructions.push_back(tmpInst);
1818 createLShiftOri<0>(Bits47To32, Reg, IDLoc, Instructions);
1820 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1821 // two left shifts of 16 bits.
1822 if (Bits31To16 == 0) {
1823 createLShiftOri<32>(Bits15To0, Reg, IDLoc, Instructions);
1825 createLShiftOri<16>(Bits31To16, Reg, IDLoc, Instructions);
1826 createLShiftOri<16>(Bits15To0, Reg, IDLoc, Instructions);
1833 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1834 SmallVectorImpl<MCInst> &Instructions) {
1836 const MCOperand &ImmOp = Inst.getOperand(2);
1837 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1838 "expected immediate operand kind");
1839 if (!ImmOp.isImm()) {
1840 expandLoadAddressSym(Inst, IDLoc, Instructions);
1843 const MCOperand &SrcRegOp = Inst.getOperand(1);
1844 assert(SrcRegOp.isReg() && "expected register operand kind");
1845 const MCOperand &DstRegOp = Inst.getOperand(0);
1846 assert(DstRegOp.isReg() && "expected register operand kind");
1847 int ImmValue = ImmOp.getImm();
1848 if (-32768 <= ImmValue && ImmValue <= 65535) {
1849 // For -32768 <= j <= 65535.
1850 // la d,j(s) => addiu d,s,j
1851 tmpInst.setOpcode(Mips::ADDiu);
1852 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1853 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1854 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1855 Instructions.push_back(tmpInst);
1857 // For any other value of j that is representable as a 32-bit integer.
1858 // la d,j(s) => lui d,hi16(j)
1861 tmpInst.setOpcode(Mips::LUi);
1862 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1863 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1864 Instructions.push_back(tmpInst);
1866 tmpInst.setOpcode(Mips::ORi);
1867 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1868 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1869 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1870 Instructions.push_back(tmpInst);
1872 tmpInst.setOpcode(Mips::ADDu);
1873 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1874 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1875 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1876 Instructions.push_back(tmpInst);
1882 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1883 SmallVectorImpl<MCInst> &Instructions) {
1885 const MCOperand &ImmOp = Inst.getOperand(1);
1886 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1887 "expected immediate operand kind");
1888 if (!ImmOp.isImm()) {
1889 expandLoadAddressSym(Inst, IDLoc, Instructions);
1892 const MCOperand &RegOp = Inst.getOperand(0);
1893 assert(RegOp.isReg() && "expected register operand kind");
1894 int ImmValue = ImmOp.getImm();
1895 if (-32768 <= ImmValue && ImmValue <= 65535) {
1896 // For -32768 <= j <= 65535.
1897 // la d,j => addiu d,$zero,j
1898 tmpInst.setOpcode(Mips::ADDiu);
1899 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1900 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1901 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1902 Instructions.push_back(tmpInst);
1904 // For any other value of j that is representable as a 32-bit integer.
1905 // la d,j => lui d,hi16(j)
1907 tmpInst.setOpcode(Mips::LUi);
1908 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1909 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1910 Instructions.push_back(tmpInst);
1912 tmpInst.setOpcode(Mips::ORi);
1913 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1914 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1915 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1916 Instructions.push_back(tmpInst);
1922 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1923 SmallVectorImpl<MCInst> &Instructions) {
1924 // FIXME: If we do have a valid at register to use, we should generate a
1925 // slightly shorter sequence here.
1927 int ExprOperandNo = 1;
1928 // Sometimes the assembly parser will get the immediate expression as
1929 // a $zero + an immediate.
1930 if (Inst.getNumOperands() == 3) {
1931 assert(Inst.getOperand(1).getReg() ==
1932 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1935 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1936 assert(SymOp.isExpr() && "expected symbol operand kind");
1937 const MCOperand &RegOp = Inst.getOperand(0);
1938 unsigned RegNo = RegOp.getReg();
1939 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1940 const MCSymbolRefExpr *HiExpr =
1941 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1942 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1943 const MCSymbolRefExpr *LoExpr =
1944 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1945 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1947 // If it's a 64-bit architecture, expand to:
1948 // la d,sym => lui d,highest(sym)
1949 // ori d,d,higher(sym)
1951 // ori d,d,hi16(sym)
1953 // ori d,d,lo16(sym)
1954 const MCSymbolRefExpr *HighestExpr =
1955 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1956 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1957 const MCSymbolRefExpr *HigherExpr =
1958 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1959 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1961 tmpInst.setOpcode(Mips::LUi);
1962 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1963 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1964 Instructions.push_back(tmpInst);
1966 createLShiftOri<0>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1968 createLShiftOri<16>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1970 createLShiftOri<16>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1973 // Otherwise, expand to:
1974 // la d,sym => lui d,hi16(sym)
1975 // ori d,d,lo16(sym)
1976 tmpInst.setOpcode(Mips::LUi);
1977 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1978 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1979 Instructions.push_back(tmpInst);
1981 createLShiftOri<0>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1986 bool MipsAsmParser::expandUncondBranchMMPseudo(
1987 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1988 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1989 "unexpected number of operands");
1991 MCOperand Offset = Inst.getOperand(0);
1992 if (Offset.isExpr()) {
1994 Inst.setOpcode(Mips::BEQ_MM);
1995 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1996 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1997 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1999 assert(Offset.isImm() && "expected immediate operand kind");
2000 if (isIntN(11, Offset.getImm())) {
2001 // If offset fits into 11 bits then this instruction becomes microMIPS
2002 // 16-bit unconditional branch instruction.
2003 Inst.setOpcode(Mips::B16_MM);
2005 if (!isIntN(17, Offset.getImm()))
2006 Error(IDLoc, "branch target out of range");
2007 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2008 Error(IDLoc, "branch to misaligned address");
2010 Inst.setOpcode(Mips::BEQ_MM);
2011 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2012 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2013 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
2016 Instructions.push_back(Inst);
2018 // If .set reorder is active, emit a NOP after the branch instruction.
2019 if (AssemblerOptions.back()->isReorder())
2020 createNop(true, IDLoc, Instructions);
2025 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2026 SmallVectorImpl<MCInst> &Instructions,
2027 bool isLoad, bool isImmOpnd) {
2028 const MCSymbolRefExpr *SR;
2030 unsigned ImmOffset, HiOffset, LoOffset;
2031 const MCExpr *ExprOffset;
2033 // 1st operand is either the source or destination register.
2034 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2035 unsigned RegOpNum = Inst.getOperand(0).getReg();
2036 // 2nd operand is the base register.
2037 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2038 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2039 // 3rd operand is either an immediate or expression.
2041 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2042 ImmOffset = Inst.getOperand(2).getImm();
2043 LoOffset = ImmOffset & 0x0000ffff;
2044 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2045 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2046 if (LoOffset & 0x8000)
2049 ExprOffset = Inst.getOperand(2).getExpr();
2050 // All instructions will have the same location.
2051 TempInst.setLoc(IDLoc);
2052 // These are some of the types of expansions we perform here:
2053 // 1) lw $8, sym => lui $8, %hi(sym)
2054 // lw $8, %lo(sym)($8)
2055 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2057 // lw $8, %lo(offset)($9)
2058 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2060 // lw $8, %lo(offset)($at)
2061 // 4) sw $8, sym => lui $at, %hi(sym)
2062 // sw $8, %lo(sym)($at)
2063 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2065 // sw $8, %lo(offset)($at)
2066 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2067 // ldc1 $f0, %lo(sym)($at)
2069 // For load instructions we can use the destination register as a temporary
2070 // if base and dst are different (examples 1 and 2) and if the base register
2071 // is general purpose otherwise we must use $at (example 6) and error if it's
2072 // not available. For stores we must use $at (examples 4 and 5) because we
2073 // must not clobber the source register setting up the offset.
2074 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2075 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2076 unsigned RegClassIDOp0 =
2077 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2078 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2079 (RegClassIDOp0 == Mips::GPR64RegClassID);
2080 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2081 TmpRegNum = RegOpNum;
2083 // At this point we need AT to perform the expansions and we exit if it is
2085 TmpRegNum = getATReg(IDLoc);
2090 TempInst.setOpcode(Mips::LUi);
2091 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2093 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2095 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2096 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2097 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2098 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2100 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2102 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2103 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2106 // Add the instruction to the list.
2107 Instructions.push_back(TempInst);
2108 // Prepare TempInst for next instruction.
2110 // Add temp register to base.
2111 if (BaseRegNum != Mips::ZERO) {
2112 TempInst.setOpcode(Mips::ADDu);
2113 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2114 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2115 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2116 Instructions.push_back(TempInst);
2119 // And finally, create original instruction with low part
2120 // of offset and new base.
2121 TempInst.setOpcode(Inst.getOpcode());
2122 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2123 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2125 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2127 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2128 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2129 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2131 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2133 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2134 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2137 Instructions.push_back(TempInst);
2142 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2143 SmallVectorImpl<MCInst> &Instructions) {
2144 unsigned OpNum = Inst.getNumOperands();
2145 unsigned Opcode = Inst.getOpcode();
2146 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2148 assert (Inst.getOperand(OpNum - 1).isImm() &&
2149 Inst.getOperand(OpNum - 2).isReg() &&
2150 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2152 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2153 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2154 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2155 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2156 // It can be implemented as SWM16 or LWM16 instruction.
2157 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2159 Inst.setOpcode(NewOpcode);
2160 Instructions.push_back(Inst);
2164 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2165 SmallVectorImpl<MCInst> &Instructions) {
2167 if (hasShortDelaySlot) {
2168 NopInst.setOpcode(Mips::MOVE16_MM);
2169 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2170 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2172 NopInst.setOpcode(Mips::SLL);
2173 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2174 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2175 NopInst.addOperand(MCOperand::CreateImm(0));
2177 Instructions.push_back(NopInst);
2180 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2181 // As described by the Mips32r2 spec, the registers Rd and Rs for
2182 // jalr.hb must be different.
2183 unsigned Opcode = Inst.getOpcode();
2185 if (Opcode == Mips::JALR_HB &&
2186 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2187 return Match_RequiresDifferentSrcAndDst;
2189 return Match_Success;
2192 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2193 OperandVector &Operands,
2195 uint64_t &ErrorInfo,
2196 bool MatchingInlineAsm) {
2199 SmallVector<MCInst, 8> Instructions;
2200 unsigned MatchResult =
2201 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2203 switch (MatchResult) {
2204 case Match_Success: {
2205 if (processInstruction(Inst, IDLoc, Instructions))
2207 for (unsigned i = 0; i < Instructions.size(); i++)
2208 Out.EmitInstruction(Instructions[i], STI);
2211 case Match_MissingFeature:
2212 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2214 case Match_InvalidOperand: {
2215 SMLoc ErrorLoc = IDLoc;
2216 if (ErrorInfo != ~0ULL) {
2217 if (ErrorInfo >= Operands.size())
2218 return Error(IDLoc, "too few operands for instruction");
2220 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2221 if (ErrorLoc == SMLoc())
2225 return Error(ErrorLoc, "invalid operand for instruction");
2227 case Match_MnemonicFail:
2228 return Error(IDLoc, "invalid instruction");
2229 case Match_RequiresDifferentSrcAndDst:
2230 return Error(IDLoc, "source and destination must be different");
2233 llvm_unreachable("Implement any new match types added!");
2236 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2237 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2238 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2239 ") without \".set noat\"");
2243 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2244 SMRange Range, bool ShowColors) {
2245 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2246 Range, SMFixIt(Range, FixMsg),
2250 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2253 CC = StringSwitch<unsigned>(Name)
2289 if (!(isABI_N32() || isABI_N64()))
2292 if (12 <= CC && CC <= 15) {
2293 // Name is one of t4-t7
2294 AsmToken RegTok = getLexer().peekTok();
2295 SMRange RegRange = RegTok.getLocRange();
2297 StringRef FixedName = StringSwitch<StringRef>(Name)
2303 assert(FixedName != "" && "Register name is not one of t4-t7.");
2305 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2306 "Did you mean $" + FixedName + "?", RegRange);
2309 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2310 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2311 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2312 if (8 <= CC && CC <= 11)
2316 CC = StringSwitch<unsigned>(Name)
2328 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2331 CC = StringSwitch<unsigned>(Name)
2332 .Case("hwr_cpunum", 0)
2333 .Case("hwr_synci_step", 1)
2335 .Case("hwr_ccres", 3)
2336 .Case("hwr_ulr", 29)
2342 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2344 if (Name[0] == 'f') {
2345 StringRef NumString = Name.substr(1);
2347 if (NumString.getAsInteger(10, IntVal))
2348 return -1; // This is not an integer.
2349 if (IntVal > 31) // Maximum index for fpu register.
2356 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2358 if (Name.startswith("fcc")) {
2359 StringRef NumString = Name.substr(3);
2361 if (NumString.getAsInteger(10, IntVal))
2362 return -1; // This is not an integer.
2363 if (IntVal > 7) // There are only 8 fcc registers.
2370 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2372 if (Name.startswith("ac")) {
2373 StringRef NumString = Name.substr(2);
2375 if (NumString.getAsInteger(10, IntVal))
2376 return -1; // This is not an integer.
2377 if (IntVal > 3) // There are only 3 acc registers.
2384 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2387 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2396 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2399 CC = StringSwitch<unsigned>(Name)
2402 .Case("msaaccess", 2)
2404 .Case("msamodify", 4)
2405 .Case("msarequest", 5)
2407 .Case("msaunmap", 7)
2413 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2414 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2416 reportParseError(Loc,
2417 "pseudo-instruction requires $at, which is not available");
2420 unsigned AT = getReg(
2421 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2425 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2426 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2429 unsigned MipsAsmParser::getGPR(int RegNo) {
2430 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2434 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2436 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2439 return getReg(RegClass, RegNum);
2442 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2443 MCAsmParser &Parser = getParser();
2444 DEBUG(dbgs() << "parseOperand\n");
2446 // Check if the current operand has a custom associated parser, if so, try to
2447 // custom parse the operand, or fallback to the general approach.
2448 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2449 if (ResTy == MatchOperand_Success)
2451 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2452 // there was a match, but an error occurred, in which case, just return that
2453 // the operand parsing failed.
2454 if (ResTy == MatchOperand_ParseFail)
2457 DEBUG(dbgs() << ".. Generic Parser\n");
2459 switch (getLexer().getKind()) {
2461 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2463 case AsmToken::Dollar: {
2464 // Parse the register.
2465 SMLoc S = Parser.getTok().getLoc();
2467 // Almost all registers have been parsed by custom parsers. There is only
2468 // one exception to this. $zero (and it's alias $0) will reach this point
2469 // for div, divu, and similar instructions because it is not an operand
2470 // to the instruction definition but an explicit register. Special case
2471 // this situation for now.
2472 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2475 // Maybe it is a symbol reference.
2476 StringRef Identifier;
2477 if (Parser.parseIdentifier(Identifier))
2480 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2481 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2482 // Otherwise create a symbol reference.
2484 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2486 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2489 // Else drop to expression parsing.
2490 case AsmToken::LParen:
2491 case AsmToken::Minus:
2492 case AsmToken::Plus:
2493 case AsmToken::Integer:
2494 case AsmToken::Tilde:
2495 case AsmToken::String: {
2496 DEBUG(dbgs() << ".. generic integer\n");
2497 OperandMatchResultTy ResTy = parseImm(Operands);
2498 return ResTy != MatchOperand_Success;
2500 case AsmToken::Percent: {
2501 // It is a symbol reference or constant expression.
2502 const MCExpr *IdVal;
2503 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2504 if (parseRelocOperand(IdVal))
2507 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2509 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2511 } // case AsmToken::Percent
2512 } // switch(getLexer().getKind())
2516 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2517 StringRef RelocStr) {
2519 // Check the type of the expression.
2520 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2521 // It's a constant, evaluate reloc value.
2523 switch (getVariantKind(RelocStr)) {
2524 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2525 // Get the 1st 16-bits.
2526 Val = MCE->getValue() & 0xffff;
2528 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2529 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2530 // 16 bits being negative.
2531 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2533 case MCSymbolRefExpr::VK_Mips_HIGHER:
2534 // Get the 3rd 16-bits.
2535 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2537 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2538 // Get the 4th 16-bits.
2539 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2542 report_fatal_error("unsupported reloc value");
2544 return MCConstantExpr::Create(Val, getContext());
2547 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2548 // It's a symbol, create a symbolic expression from the symbol.
2549 StringRef Symbol = MSRE->getSymbol().getName();
2550 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2551 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2555 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2556 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2558 // Try to create target expression.
2559 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2560 return MipsMCExpr::Create(VK, Expr, getContext());
2562 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2563 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2564 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2568 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2569 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2570 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2573 // Just return the original expression.
2577 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2579 switch (Expr->getKind()) {
2580 case MCExpr::Constant:
2582 case MCExpr::SymbolRef:
2583 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2584 case MCExpr::Binary:
2585 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2586 if (!isEvaluated(BE->getLHS()))
2588 return isEvaluated(BE->getRHS());
2591 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2592 case MCExpr::Target:
2598 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2599 MCAsmParser &Parser = getParser();
2600 Parser.Lex(); // Eat the % token.
2601 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2602 if (Tok.isNot(AsmToken::Identifier))
2605 std::string Str = Tok.getIdentifier();
2607 Parser.Lex(); // Eat the identifier.
2608 // Now make an expression from the rest of the operand.
2609 const MCExpr *IdVal;
2612 if (getLexer().getKind() == AsmToken::LParen) {
2614 Parser.Lex(); // Eat the '(' token.
2615 if (getLexer().getKind() == AsmToken::Percent) {
2616 Parser.Lex(); // Eat the % token.
2617 const AsmToken &nextTok = Parser.getTok();
2618 if (nextTok.isNot(AsmToken::Identifier))
2621 Str += nextTok.getIdentifier();
2622 Parser.Lex(); // Eat the identifier.
2623 if (getLexer().getKind() != AsmToken::LParen)
2628 if (getParser().parseParenExpression(IdVal, EndLoc))
2631 while (getLexer().getKind() == AsmToken::RParen)
2632 Parser.Lex(); // Eat the ')' token.
2635 return true; // Parenthesis must follow the relocation operand.
2637 Res = evaluateRelocExpr(IdVal, Str);
2641 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2643 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2644 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2645 if (ResTy == MatchOperand_Success) {
2646 assert(Operands.size() == 1);
2647 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2648 StartLoc = Operand.getStartLoc();
2649 EndLoc = Operand.getEndLoc();
2651 // AFAIK, we only support numeric registers and named GPR's in CFI
2653 // Don't worry about eating tokens before failing. Using an unrecognised
2654 // register is a parse error.
2655 if (Operand.isGPRAsmReg()) {
2656 // Resolve to GPR32 or GPR64 appropriately.
2657 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2660 return (RegNo == (unsigned)-1);
2663 assert(Operands.size() == 0);
2664 return (RegNo == (unsigned)-1);
2667 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2668 MCAsmParser &Parser = getParser();
2672 while (getLexer().getKind() == AsmToken::LParen)
2675 switch (getLexer().getKind()) {
2678 case AsmToken::Identifier:
2679 case AsmToken::LParen:
2680 case AsmToken::Integer:
2681 case AsmToken::Minus:
2682 case AsmToken::Plus:
2684 Result = getParser().parseParenExpression(Res, S);
2686 Result = (getParser().parseExpression(Res));
2687 while (getLexer().getKind() == AsmToken::RParen)
2690 case AsmToken::Percent:
2691 Result = parseRelocOperand(Res);
2696 MipsAsmParser::OperandMatchResultTy
2697 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2698 MCAsmParser &Parser = getParser();
2699 DEBUG(dbgs() << "parseMemOperand\n");
2700 const MCExpr *IdVal = nullptr;
2702 bool isParenExpr = false;
2703 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2704 // First operand is the offset.
2705 S = Parser.getTok().getLoc();
2707 if (getLexer().getKind() == AsmToken::LParen) {
2712 if (getLexer().getKind() != AsmToken::Dollar) {
2713 if (parseMemOffset(IdVal, isParenExpr))
2714 return MatchOperand_ParseFail;
2716 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2717 if (Tok.isNot(AsmToken::LParen)) {
2718 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2719 if (Mnemonic.getToken() == "la") {
2721 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2722 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2723 return MatchOperand_Success;
2725 if (Tok.is(AsmToken::EndOfStatement)) {
2727 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2729 // Zero register assumed, add a memory operand with ZERO as its base.
2730 // "Base" will be managed by k_Memory.
2731 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2734 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2735 return MatchOperand_Success;
2737 Error(Parser.getTok().getLoc(), "'(' expected");
2738 return MatchOperand_ParseFail;
2741 Parser.Lex(); // Eat the '(' token.
2744 Res = parseAnyRegister(Operands);
2745 if (Res != MatchOperand_Success)
2748 if (Parser.getTok().isNot(AsmToken::RParen)) {
2749 Error(Parser.getTok().getLoc(), "')' expected");
2750 return MatchOperand_ParseFail;
2753 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2755 Parser.Lex(); // Eat the ')' token.
2758 IdVal = MCConstantExpr::Create(0, getContext());
2760 // Replace the register operand with the memory operand.
2761 std::unique_ptr<MipsOperand> op(
2762 static_cast<MipsOperand *>(Operands.back().release()));
2763 // Remove the register from the operands.
2764 // "op" will be managed by k_Memory.
2765 Operands.pop_back();
2766 // Add the memory operand.
2767 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2769 if (IdVal->EvaluateAsAbsolute(Imm))
2770 IdVal = MCConstantExpr::Create(Imm, getContext());
2771 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2772 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2776 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2777 return MatchOperand_Success;
2780 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2781 MCAsmParser &Parser = getParser();
2782 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2784 SMLoc S = Parser.getTok().getLoc();
2786 if (Sym->isVariable())
2787 Expr = Sym->getVariableValue();
2790 if (Expr->getKind() == MCExpr::SymbolRef) {
2791 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2792 StringRef DefSymbol = Ref->getSymbol().getName();
2793 if (DefSymbol.startswith("$")) {
2794 OperandMatchResultTy ResTy =
2795 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2796 if (ResTy == MatchOperand_Success) {
2799 } else if (ResTy == MatchOperand_ParseFail)
2800 llvm_unreachable("Should never ParseFail");
2803 } else if (Expr->getKind() == MCExpr::Constant) {
2805 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2807 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2814 MipsAsmParser::OperandMatchResultTy
2815 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2816 StringRef Identifier,
2818 int Index = matchCPURegisterName(Identifier);
2820 Operands.push_back(MipsOperand::createGPRReg(
2821 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2822 return MatchOperand_Success;
2825 Index = matchHWRegsRegisterName(Identifier);
2827 Operands.push_back(MipsOperand::createHWRegsReg(
2828 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2829 return MatchOperand_Success;
2832 Index = matchFPURegisterName(Identifier);
2834 Operands.push_back(MipsOperand::createFGRReg(
2835 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2836 return MatchOperand_Success;
2839 Index = matchFCCRegisterName(Identifier);
2841 Operands.push_back(MipsOperand::createFCCReg(
2842 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2843 return MatchOperand_Success;
2846 Index = matchACRegisterName(Identifier);
2848 Operands.push_back(MipsOperand::createACCReg(
2849 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2850 return MatchOperand_Success;
2853 Index = matchMSA128RegisterName(Identifier);
2855 Operands.push_back(MipsOperand::createMSA128Reg(
2856 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2857 return MatchOperand_Success;
2860 Index = matchMSA128CtrlRegisterName(Identifier);
2862 Operands.push_back(MipsOperand::createMSACtrlReg(
2863 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2864 return MatchOperand_Success;
2867 return MatchOperand_NoMatch;
2870 MipsAsmParser::OperandMatchResultTy
2871 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2872 MCAsmParser &Parser = getParser();
2873 auto Token = Parser.getLexer().peekTok(false);
2875 if (Token.is(AsmToken::Identifier)) {
2876 DEBUG(dbgs() << ".. identifier\n");
2877 StringRef Identifier = Token.getIdentifier();
2878 OperandMatchResultTy ResTy =
2879 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2881 } else if (Token.is(AsmToken::Integer)) {
2882 DEBUG(dbgs() << ".. integer\n");
2883 Operands.push_back(MipsOperand::createNumericReg(
2884 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2886 return MatchOperand_Success;
2889 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2891 return MatchOperand_NoMatch;
2894 MipsAsmParser::OperandMatchResultTy
2895 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2896 MCAsmParser &Parser = getParser();
2897 DEBUG(dbgs() << "parseAnyRegister\n");
2899 auto Token = Parser.getTok();
2901 SMLoc S = Token.getLoc();
2903 if (Token.isNot(AsmToken::Dollar)) {
2904 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2905 if (Token.is(AsmToken::Identifier)) {
2906 if (searchSymbolAlias(Operands))
2907 return MatchOperand_Success;
2909 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2910 return MatchOperand_NoMatch;
2912 DEBUG(dbgs() << ".. $\n");
2914 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2915 if (ResTy == MatchOperand_Success) {
2917 Parser.Lex(); // identifier
2922 MipsAsmParser::OperandMatchResultTy
2923 MipsAsmParser::parseImm(OperandVector &Operands) {
2924 MCAsmParser &Parser = getParser();
2925 switch (getLexer().getKind()) {
2927 return MatchOperand_NoMatch;
2928 case AsmToken::LParen:
2929 case AsmToken::Minus:
2930 case AsmToken::Plus:
2931 case AsmToken::Integer:
2932 case AsmToken::Tilde:
2933 case AsmToken::String:
2937 const MCExpr *IdVal;
2938 SMLoc S = Parser.getTok().getLoc();
2939 if (getParser().parseExpression(IdVal))
2940 return MatchOperand_ParseFail;
2942 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2943 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2944 return MatchOperand_Success;
2947 MipsAsmParser::OperandMatchResultTy
2948 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2949 MCAsmParser &Parser = getParser();
2950 DEBUG(dbgs() << "parseJumpTarget\n");
2952 SMLoc S = getLexer().getLoc();
2954 // Integers and expressions are acceptable
2955 OperandMatchResultTy ResTy = parseImm(Operands);
2956 if (ResTy != MatchOperand_NoMatch)
2959 // Registers are a valid target and have priority over symbols.
2960 ResTy = parseAnyRegister(Operands);
2961 if (ResTy != MatchOperand_NoMatch)
2964 const MCExpr *Expr = nullptr;
2965 if (Parser.parseExpression(Expr)) {
2966 // We have no way of knowing if a symbol was consumed so we must ParseFail
2967 return MatchOperand_ParseFail;
2970 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2971 return MatchOperand_Success;
2974 MipsAsmParser::OperandMatchResultTy
2975 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2976 MCAsmParser &Parser = getParser();
2977 const MCExpr *IdVal;
2978 // If the first token is '$' we may have register operand.
2979 if (Parser.getTok().is(AsmToken::Dollar))
2980 return MatchOperand_NoMatch;
2981 SMLoc S = Parser.getTok().getLoc();
2982 if (getParser().parseExpression(IdVal))
2983 return MatchOperand_ParseFail;
2984 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2985 assert(MCE && "Unexpected MCExpr type.");
2986 int64_t Val = MCE->getValue();
2987 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2988 Operands.push_back(MipsOperand::CreateImm(
2989 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2990 return MatchOperand_Success;
2993 MipsAsmParser::OperandMatchResultTy
2994 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2995 MCAsmParser &Parser = getParser();
2996 switch (getLexer().getKind()) {
2998 return MatchOperand_NoMatch;
2999 case AsmToken::LParen:
3000 case AsmToken::Plus:
3001 case AsmToken::Minus:
3002 case AsmToken::Integer:
3007 SMLoc S = Parser.getTok().getLoc();
3009 if (getParser().parseExpression(Expr))
3010 return MatchOperand_ParseFail;
3013 if (!Expr->EvaluateAsAbsolute(Val)) {
3014 Error(S, "expected immediate value");
3015 return MatchOperand_ParseFail;
3018 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3019 // and because the CPU always adds one to the immediate field, the allowed
3020 // range becomes 1..4. We'll only check the range here and will deal
3021 // with the addition/subtraction when actually decoding/encoding
3023 if (Val < 1 || Val > 4) {
3024 Error(S, "immediate not in range (1..4)");
3025 return MatchOperand_ParseFail;
3029 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3030 return MatchOperand_Success;
3033 MipsAsmParser::OperandMatchResultTy
3034 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3035 MCAsmParser &Parser = getParser();
3036 SmallVector<unsigned, 10> Regs;
3038 unsigned PrevReg = Mips::NoRegister;
3039 bool RegRange = false;
3040 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3042 if (Parser.getTok().isNot(AsmToken::Dollar))
3043 return MatchOperand_ParseFail;
3045 SMLoc S = Parser.getTok().getLoc();
3046 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3047 SMLoc E = getLexer().getLoc();
3048 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3049 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3051 // Remove last register operand because registers from register range
3052 // should be inserted first.
3053 if (RegNo == Mips::RA) {
3054 Regs.push_back(RegNo);
3056 unsigned TmpReg = PrevReg + 1;
3057 while (TmpReg <= RegNo) {
3058 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3059 Error(E, "invalid register operand");
3060 return MatchOperand_ParseFail;
3064 Regs.push_back(TmpReg++);
3070 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3071 (RegNo != Mips::RA)) {
3072 Error(E, "$16 or $31 expected");
3073 return MatchOperand_ParseFail;
3074 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3075 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3076 Error(E, "invalid register operand");
3077 return MatchOperand_ParseFail;
3078 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3079 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3080 Error(E, "consecutive register numbers expected");
3081 return MatchOperand_ParseFail;
3084 Regs.push_back(RegNo);
3087 if (Parser.getTok().is(AsmToken::Minus))
3090 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3091 !Parser.getTok().isNot(AsmToken::Comma)) {
3092 Error(E, "',' or '-' expected");
3093 return MatchOperand_ParseFail;
3096 Lex(); // Consume comma or minus
3097 if (Parser.getTok().isNot(AsmToken::Dollar))
3103 SMLoc E = Parser.getTok().getLoc();
3104 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3105 parseMemOperand(Operands);
3106 return MatchOperand_Success;
3109 MipsAsmParser::OperandMatchResultTy
3110 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3111 MCAsmParser &Parser = getParser();
3113 SMLoc S = Parser.getTok().getLoc();
3114 if (parseAnyRegister(Operands) != MatchOperand_Success)
3115 return MatchOperand_ParseFail;
3117 SMLoc E = Parser.getTok().getLoc();
3118 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3119 unsigned Reg = Op.getGPR32Reg();
3120 Operands.pop_back();
3121 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3122 return MatchOperand_Success;
3125 MipsAsmParser::OperandMatchResultTy
3126 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3127 MCAsmParser &Parser = getParser();
3128 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3129 SmallVector<unsigned, 10> Regs;
3131 if (Parser.getTok().isNot(AsmToken::Dollar))
3132 return MatchOperand_ParseFail;
3134 SMLoc S = Parser.getTok().getLoc();
3136 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3137 return MatchOperand_ParseFail;
3139 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3140 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3141 Regs.push_back(RegNo);
3143 SMLoc E = Parser.getTok().getLoc();
3144 if (Parser.getTok().isNot(AsmToken::Comma)) {
3145 Error(E, "',' expected");
3146 return MatchOperand_ParseFail;
3152 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3153 return MatchOperand_ParseFail;
3155 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3156 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3157 Regs.push_back(RegNo);
3159 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3161 return MatchOperand_Success;
3164 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3166 MCSymbolRefExpr::VariantKind VK =
3167 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3168 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3169 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3170 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3171 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3172 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3173 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3174 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3175 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3176 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3177 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3178 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3179 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3180 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3181 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3182 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3183 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3184 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3185 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3186 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3187 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3188 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3189 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3190 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3191 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3192 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3193 .Default(MCSymbolRefExpr::VK_None);
3195 assert(VK != MCSymbolRefExpr::VK_None);
3200 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3202 /// ::= '(', register, ')'
3203 /// handle it before we iterate so we don't get tripped up by the lack of
3205 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3206 MCAsmParser &Parser = getParser();
3207 if (getLexer().is(AsmToken::LParen)) {
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::RParen)) {
3217 SMLoc Loc = getLexer().getLoc();
3218 Parser.eatToEndOfStatement();
3219 return Error(Loc, "unexpected token, expected ')'");
3222 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3228 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3229 /// either one of these.
3230 /// ::= '[', register, ']'
3231 /// ::= '[', integer, ']'
3232 /// handle it before we iterate so we don't get tripped up by the lack of
3234 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3235 OperandVector &Operands) {
3236 MCAsmParser &Parser = getParser();
3237 if (getLexer().is(AsmToken::LBrac)) {
3239 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3241 if (parseOperand(Operands, Name)) {
3242 SMLoc Loc = getLexer().getLoc();
3243 Parser.eatToEndOfStatement();
3244 return Error(Loc, "unexpected token in argument list");
3246 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3247 SMLoc Loc = getLexer().getLoc();
3248 Parser.eatToEndOfStatement();
3249 return Error(Loc, "unexpected token, expected ']'");
3252 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3258 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3259 SMLoc NameLoc, OperandVector &Operands) {
3260 MCAsmParser &Parser = getParser();
3261 DEBUG(dbgs() << "ParseInstruction\n");
3263 // We have reached first instruction, module directive are now forbidden.
3264 getTargetStreamer().forbidModuleDirective();
3266 // Check if we have valid mnemonic
3267 if (!mnemonicIsValid(Name, 0)) {
3268 Parser.eatToEndOfStatement();
3269 return Error(NameLoc, "unknown instruction");
3271 // First operand in MCInst is instruction mnemonic.
3272 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3274 // Read the remaining operands.
3275 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3276 // Read the first operand.
3277 if (parseOperand(Operands, Name)) {
3278 SMLoc Loc = getLexer().getLoc();
3279 Parser.eatToEndOfStatement();
3280 return Error(Loc, "unexpected token in argument list");
3282 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3284 // AFAIK, parenthesis suffixes are never on the first operand
3286 while (getLexer().is(AsmToken::Comma)) {
3287 Parser.Lex(); // Eat the comma.
3288 // Parse and remember the operand.
3289 if (parseOperand(Operands, Name)) {
3290 SMLoc Loc = getLexer().getLoc();
3291 Parser.eatToEndOfStatement();
3292 return Error(Loc, "unexpected token in argument list");
3294 // Parse bracket and parenthesis suffixes before we iterate
3295 if (getLexer().is(AsmToken::LBrac)) {
3296 if (parseBracketSuffix(Name, Operands))
3298 } else if (getLexer().is(AsmToken::LParen) &&
3299 parseParenSuffix(Name, Operands))
3303 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3304 SMLoc Loc = getLexer().getLoc();
3305 Parser.eatToEndOfStatement();
3306 return Error(Loc, "unexpected token in argument list");
3308 Parser.Lex(); // Consume the EndOfStatement.
3312 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3313 MCAsmParser &Parser = getParser();
3314 SMLoc Loc = getLexer().getLoc();
3315 Parser.eatToEndOfStatement();
3316 return Error(Loc, ErrorMsg);
3319 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3320 return Error(Loc, ErrorMsg);
3323 bool MipsAsmParser::parseSetNoAtDirective() {
3324 MCAsmParser &Parser = getParser();
3325 // Line should look like: ".set noat".
3327 // Set the $at register to $0.
3328 AssemblerOptions.back()->setATRegIndex(0);
3330 Parser.Lex(); // Eat "noat".
3332 // If this is not the end of the statement, report an error.
3333 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3334 reportParseError("unexpected token, expected end of statement");
3338 getTargetStreamer().emitDirectiveSetNoAt();
3339 Parser.Lex(); // Consume the EndOfStatement.
3343 bool MipsAsmParser::parseSetAtDirective() {
3344 // Line can be: ".set at", which sets $at to $1
3345 // or ".set at=$reg", which sets $at to $reg.
3346 MCAsmParser &Parser = getParser();
3347 Parser.Lex(); // Eat "at".
3349 if (getLexer().is(AsmToken::EndOfStatement)) {
3350 // No register was specified, so we set $at to $1.
3351 AssemblerOptions.back()->setATRegIndex(1);
3353 getTargetStreamer().emitDirectiveSetAt();
3354 Parser.Lex(); // Consume the EndOfStatement.
3358 if (getLexer().isNot(AsmToken::Equal)) {
3359 reportParseError("unexpected token, expected equals sign");
3362 Parser.Lex(); // Eat "=".
3364 if (getLexer().isNot(AsmToken::Dollar)) {
3365 if (getLexer().is(AsmToken::EndOfStatement)) {
3366 reportParseError("no register specified");
3369 reportParseError("unexpected token, expected dollar sign '$'");
3373 Parser.Lex(); // Eat "$".
3375 // Find out what "reg" is.
3377 const AsmToken &Reg = Parser.getTok();
3378 if (Reg.is(AsmToken::Identifier)) {
3379 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3380 } else if (Reg.is(AsmToken::Integer)) {
3381 AtRegNo = Reg.getIntVal();
3383 reportParseError("unexpected token, expected identifier or integer");
3387 // Check if $reg is a valid register. If it is, set $at to $reg.
3388 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3389 reportParseError("invalid register");
3392 Parser.Lex(); // Eat "reg".
3394 // If this is not the end of the statement, report an error.
3395 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3396 reportParseError("unexpected token, expected end of statement");
3400 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3402 Parser.Lex(); // Consume the EndOfStatement.
3406 bool MipsAsmParser::parseSetReorderDirective() {
3407 MCAsmParser &Parser = getParser();
3409 // If this is not the end of the statement, report an error.
3410 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3411 reportParseError("unexpected token, expected end of statement");
3414 AssemblerOptions.back()->setReorder();
3415 getTargetStreamer().emitDirectiveSetReorder();
3416 Parser.Lex(); // Consume the EndOfStatement.
3420 bool MipsAsmParser::parseSetNoReorderDirective() {
3421 MCAsmParser &Parser = getParser();
3423 // If this is not the end of the statement, report an error.
3424 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3425 reportParseError("unexpected token, expected end of statement");
3428 AssemblerOptions.back()->setNoReorder();
3429 getTargetStreamer().emitDirectiveSetNoReorder();
3430 Parser.Lex(); // Consume the EndOfStatement.
3434 bool MipsAsmParser::parseSetMacroDirective() {
3435 MCAsmParser &Parser = getParser();
3437 // If this is not the end of the statement, report an error.
3438 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3439 reportParseError("unexpected token, expected end of statement");
3442 AssemblerOptions.back()->setMacro();
3443 Parser.Lex(); // Consume the EndOfStatement.
3447 bool MipsAsmParser::parseSetNoMacroDirective() {
3448 MCAsmParser &Parser = getParser();
3450 // If this is not the end of the statement, report an error.
3451 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3452 reportParseError("unexpected token, expected end of statement");
3455 if (AssemblerOptions.back()->isReorder()) {
3456 reportParseError("`noreorder' must be set before `nomacro'");
3459 AssemblerOptions.back()->setNoMacro();
3460 Parser.Lex(); // Consume the EndOfStatement.
3464 bool MipsAsmParser::parseSetMsaDirective() {
3465 MCAsmParser &Parser = getParser();
3468 // If this is not the end of the statement, report an error.
3469 if (getLexer().isNot(AsmToken::EndOfStatement))
3470 return reportParseError("unexpected token, expected end of statement");
3472 setFeatureBits(Mips::FeatureMSA, "msa");
3473 getTargetStreamer().emitDirectiveSetMsa();
3477 bool MipsAsmParser::parseSetNoMsaDirective() {
3478 MCAsmParser &Parser = getParser();
3481 // If this is not the end of the statement, report an error.
3482 if (getLexer().isNot(AsmToken::EndOfStatement))
3483 return reportParseError("unexpected token, expected end of statement");
3485 clearFeatureBits(Mips::FeatureMSA, "msa");
3486 getTargetStreamer().emitDirectiveSetNoMsa();
3490 bool MipsAsmParser::parseSetNoDspDirective() {
3491 MCAsmParser &Parser = getParser();
3492 Parser.Lex(); // Eat "nodsp".
3494 // If this is not the end of the statement, report an error.
3495 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3496 reportParseError("unexpected token, expected end of statement");
3500 clearFeatureBits(Mips::FeatureDSP, "dsp");
3501 getTargetStreamer().emitDirectiveSetNoDsp();
3505 bool MipsAsmParser::parseSetMips16Directive() {
3506 MCAsmParser &Parser = getParser();
3507 Parser.Lex(); // Eat "mips16".
3509 // If this is not the end of the statement, report an error.
3510 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3511 reportParseError("unexpected token, expected end of statement");
3515 setFeatureBits(Mips::FeatureMips16, "mips16");
3516 getTargetStreamer().emitDirectiveSetMips16();
3517 Parser.Lex(); // Consume the EndOfStatement.
3521 bool MipsAsmParser::parseSetNoMips16Directive() {
3522 MCAsmParser &Parser = getParser();
3523 Parser.Lex(); // Eat "nomips16".
3525 // If this is not the end of the statement, report an error.
3526 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3527 reportParseError("unexpected token, expected end of statement");
3531 clearFeatureBits(Mips::FeatureMips16, "mips16");
3532 getTargetStreamer().emitDirectiveSetNoMips16();
3533 Parser.Lex(); // Consume the EndOfStatement.
3537 bool MipsAsmParser::parseSetFpDirective() {
3538 MCAsmParser &Parser = getParser();
3539 MipsABIFlagsSection::FpABIKind FpAbiVal;
3540 // Line can be: .set fp=32
3543 Parser.Lex(); // Eat fp token
3544 AsmToken Tok = Parser.getTok();
3545 if (Tok.isNot(AsmToken::Equal)) {
3546 reportParseError("unexpected token, expected equals sign '='");
3549 Parser.Lex(); // Eat '=' token.
3550 Tok = Parser.getTok();
3552 if (!parseFpABIValue(FpAbiVal, ".set"))
3555 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3556 reportParseError("unexpected token, expected end of statement");
3559 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3560 Parser.Lex(); // Consume the EndOfStatement.
3564 bool MipsAsmParser::parseSetPopDirective() {
3565 MCAsmParser &Parser = getParser();
3566 SMLoc Loc = getLexer().getLoc();
3569 if (getLexer().isNot(AsmToken::EndOfStatement))
3570 return reportParseError("unexpected token, expected end of statement");
3572 // Always keep an element on the options "stack" to prevent the user
3573 // from changing the initial options. This is how we remember them.
3574 if (AssemblerOptions.size() == 2)
3575 return reportParseError(Loc, ".set pop with no .set push");
3577 AssemblerOptions.pop_back();
3578 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3580 getTargetStreamer().emitDirectiveSetPop();
3584 bool MipsAsmParser::parseSetPushDirective() {
3585 MCAsmParser &Parser = getParser();
3587 if (getLexer().isNot(AsmToken::EndOfStatement))
3588 return reportParseError("unexpected token, expected end of statement");
3590 // Create a copy of the current assembler options environment and push it.
3591 AssemblerOptions.push_back(
3592 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3594 getTargetStreamer().emitDirectiveSetPush();
3598 bool MipsAsmParser::parseSetAssignment() {
3600 const MCExpr *Value;
3601 MCAsmParser &Parser = getParser();
3603 if (Parser.parseIdentifier(Name))
3604 reportParseError("expected identifier after .set");
3606 if (getLexer().isNot(AsmToken::Comma))
3607 return reportParseError("unexpected token, expected comma");
3610 if (Parser.parseExpression(Value))
3611 return reportParseError("expected valid expression after comma");
3613 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3614 Sym->setVariableValue(Value);
3619 bool MipsAsmParser::parseSetMips0Directive() {
3620 MCAsmParser &Parser = getParser();
3622 if (getLexer().isNot(AsmToken::EndOfStatement))
3623 return reportParseError("unexpected token, expected end of statement");
3625 // Reset assembler options to their initial values.
3626 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3627 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3629 getTargetStreamer().emitDirectiveSetMips0();
3633 bool MipsAsmParser::parseSetArchDirective() {
3634 MCAsmParser &Parser = getParser();
3636 if (getLexer().isNot(AsmToken::Equal))
3637 return reportParseError("unexpected token, expected equals sign");
3641 if (Parser.parseIdentifier(Arch))
3642 return reportParseError("expected arch identifier");
3644 StringRef ArchFeatureName =
3645 StringSwitch<StringRef>(Arch)
3646 .Case("mips1", "mips1")
3647 .Case("mips2", "mips2")
3648 .Case("mips3", "mips3")
3649 .Case("mips4", "mips4")
3650 .Case("mips5", "mips5")
3651 .Case("mips32", "mips32")
3652 .Case("mips32r2", "mips32r2")
3653 .Case("mips32r3", "mips32r3")
3654 .Case("mips32r5", "mips32r5")
3655 .Case("mips32r6", "mips32r6")
3656 .Case("mips64", "mips64")
3657 .Case("mips64r2", "mips64r2")
3658 .Case("mips64r3", "mips64r3")
3659 .Case("mips64r5", "mips64r5")
3660 .Case("mips64r6", "mips64r6")
3661 .Case("cnmips", "cnmips")
3662 .Case("r4000", "mips3") // This is an implementation of Mips3.
3665 if (ArchFeatureName.empty())
3666 return reportParseError("unsupported architecture");
3668 selectArch(ArchFeatureName);
3669 getTargetStreamer().emitDirectiveSetArch(Arch);
3673 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3674 MCAsmParser &Parser = getParser();
3676 if (getLexer().isNot(AsmToken::EndOfStatement))
3677 return reportParseError("unexpected token, expected end of statement");
3681 llvm_unreachable("Unimplemented feature");
3682 case Mips::FeatureDSP:
3683 setFeatureBits(Mips::FeatureDSP, "dsp");
3684 getTargetStreamer().emitDirectiveSetDsp();
3686 case Mips::FeatureMicroMips:
3687 getTargetStreamer().emitDirectiveSetMicroMips();
3689 case Mips::FeatureMips1:
3690 selectArch("mips1");
3691 getTargetStreamer().emitDirectiveSetMips1();
3693 case Mips::FeatureMips2:
3694 selectArch("mips2");
3695 getTargetStreamer().emitDirectiveSetMips2();
3697 case Mips::FeatureMips3:
3698 selectArch("mips3");
3699 getTargetStreamer().emitDirectiveSetMips3();
3701 case Mips::FeatureMips4:
3702 selectArch("mips4");
3703 getTargetStreamer().emitDirectiveSetMips4();
3705 case Mips::FeatureMips5:
3706 selectArch("mips5");
3707 getTargetStreamer().emitDirectiveSetMips5();
3709 case Mips::FeatureMips32:
3710 selectArch("mips32");
3711 getTargetStreamer().emitDirectiveSetMips32();
3713 case Mips::FeatureMips32r2:
3714 selectArch("mips32r2");
3715 getTargetStreamer().emitDirectiveSetMips32R2();
3717 case Mips::FeatureMips32r3:
3718 selectArch("mips32r3");
3719 getTargetStreamer().emitDirectiveSetMips32R3();
3721 case Mips::FeatureMips32r5:
3722 selectArch("mips32r5");
3723 getTargetStreamer().emitDirectiveSetMips32R5();
3725 case Mips::FeatureMips32r6:
3726 selectArch("mips32r6");
3727 getTargetStreamer().emitDirectiveSetMips32R6();
3729 case Mips::FeatureMips64:
3730 selectArch("mips64");
3731 getTargetStreamer().emitDirectiveSetMips64();
3733 case Mips::FeatureMips64r2:
3734 selectArch("mips64r2");
3735 getTargetStreamer().emitDirectiveSetMips64R2();
3737 case Mips::FeatureMips64r3:
3738 selectArch("mips64r3");
3739 getTargetStreamer().emitDirectiveSetMips64R3();
3741 case Mips::FeatureMips64r5:
3742 selectArch("mips64r5");
3743 getTargetStreamer().emitDirectiveSetMips64R5();
3745 case Mips::FeatureMips64r6:
3746 selectArch("mips64r6");
3747 getTargetStreamer().emitDirectiveSetMips64R6();
3753 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3754 MCAsmParser &Parser = getParser();
3755 if (getLexer().isNot(AsmToken::Comma)) {
3756 SMLoc Loc = getLexer().getLoc();
3757 Parser.eatToEndOfStatement();
3758 return Error(Loc, ErrorStr);
3761 Parser.Lex(); // Eat the comma.
3765 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3766 if (AssemblerOptions.back()->isReorder())
3767 Warning(Loc, ".cpload should be inside a noreorder section");
3769 if (inMips16Mode()) {
3770 reportParseError(".cpload is not supported in Mips16 mode");
3774 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3775 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3776 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3777 reportParseError("expected register containing function address");
3781 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3782 if (!RegOpnd.isGPRAsmReg()) {
3783 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3787 // If this is not the end of the statement, report an error.
3788 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3789 reportParseError("unexpected token, expected end of statement");
3793 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3797 bool MipsAsmParser::parseDirectiveCPSetup() {
3798 MCAsmParser &Parser = getParser();
3801 bool SaveIsReg = true;
3803 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3804 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3805 if (ResTy == MatchOperand_NoMatch) {
3806 reportParseError("expected register containing function address");
3807 Parser.eatToEndOfStatement();
3811 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3812 if (!FuncRegOpnd.isGPRAsmReg()) {
3813 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3814 Parser.eatToEndOfStatement();
3818 FuncReg = FuncRegOpnd.getGPR32Reg();
3821 if (!eatComma("unexpected token, expected comma"))
3824 ResTy = parseAnyRegister(TmpReg);
3825 if (ResTy == MatchOperand_NoMatch) {
3826 const AsmToken &Tok = Parser.getTok();
3827 if (Tok.is(AsmToken::Integer)) {
3828 Save = Tok.getIntVal();
3832 reportParseError("expected save register or stack offset");
3833 Parser.eatToEndOfStatement();
3837 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3838 if (!SaveOpnd.isGPRAsmReg()) {
3839 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3840 Parser.eatToEndOfStatement();
3843 Save = SaveOpnd.getGPR32Reg();
3846 if (!eatComma("unexpected token, expected comma"))
3850 if (Parser.parseExpression(Expr)) {
3851 reportParseError("expected expression");
3855 if (Expr->getKind() != MCExpr::SymbolRef) {
3856 reportParseError("expected symbol");
3859 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3861 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3866 bool MipsAsmParser::parseDirectiveNaN() {
3867 MCAsmParser &Parser = getParser();
3868 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3869 const AsmToken &Tok = Parser.getTok();
3871 if (Tok.getString() == "2008") {
3873 getTargetStreamer().emitDirectiveNaN2008();
3875 } else if (Tok.getString() == "legacy") {
3877 getTargetStreamer().emitDirectiveNaNLegacy();
3881 // If we don't recognize the option passed to the .nan
3882 // directive (e.g. no option or unknown option), emit an error.
3883 reportParseError("invalid option in .nan directive");
3887 bool MipsAsmParser::parseDirectiveSet() {
3888 MCAsmParser &Parser = getParser();
3889 // Get the next token.
3890 const AsmToken &Tok = Parser.getTok();
3892 if (Tok.getString() == "noat") {
3893 return parseSetNoAtDirective();
3894 } else if (Tok.getString() == "at") {
3895 return parseSetAtDirective();
3896 } else if (Tok.getString() == "arch") {
3897 return parseSetArchDirective();
3898 } else if (Tok.getString() == "fp") {
3899 return parseSetFpDirective();
3900 } else if (Tok.getString() == "pop") {
3901 return parseSetPopDirective();
3902 } else if (Tok.getString() == "push") {
3903 return parseSetPushDirective();
3904 } else if (Tok.getString() == "reorder") {
3905 return parseSetReorderDirective();
3906 } else if (Tok.getString() == "noreorder") {
3907 return parseSetNoReorderDirective();
3908 } else if (Tok.getString() == "macro") {
3909 return parseSetMacroDirective();
3910 } else if (Tok.getString() == "nomacro") {
3911 return parseSetNoMacroDirective();
3912 } else if (Tok.getString() == "mips16") {
3913 return parseSetMips16Directive();
3914 } else if (Tok.getString() == "nomips16") {
3915 return parseSetNoMips16Directive();
3916 } else if (Tok.getString() == "nomicromips") {
3917 getTargetStreamer().emitDirectiveSetNoMicroMips();
3918 Parser.eatToEndOfStatement();
3920 } else if (Tok.getString() == "micromips") {
3921 return parseSetFeature(Mips::FeatureMicroMips);
3922 } else if (Tok.getString() == "mips0") {
3923 return parseSetMips0Directive();
3924 } else if (Tok.getString() == "mips1") {
3925 return parseSetFeature(Mips::FeatureMips1);
3926 } else if (Tok.getString() == "mips2") {
3927 return parseSetFeature(Mips::FeatureMips2);
3928 } else if (Tok.getString() == "mips3") {
3929 return parseSetFeature(Mips::FeatureMips3);
3930 } else if (Tok.getString() == "mips4") {
3931 return parseSetFeature(Mips::FeatureMips4);
3932 } else if (Tok.getString() == "mips5") {
3933 return parseSetFeature(Mips::FeatureMips5);
3934 } else if (Tok.getString() == "mips32") {
3935 return parseSetFeature(Mips::FeatureMips32);
3936 } else if (Tok.getString() == "mips32r2") {
3937 return parseSetFeature(Mips::FeatureMips32r2);
3938 } else if (Tok.getString() == "mips32r3") {
3939 return parseSetFeature(Mips::FeatureMips32r3);
3940 } else if (Tok.getString() == "mips32r5") {
3941 return parseSetFeature(Mips::FeatureMips32r5);
3942 } else if (Tok.getString() == "mips32r6") {
3943 return parseSetFeature(Mips::FeatureMips32r6);
3944 } else if (Tok.getString() == "mips64") {
3945 return parseSetFeature(Mips::FeatureMips64);
3946 } else if (Tok.getString() == "mips64r2") {
3947 return parseSetFeature(Mips::FeatureMips64r2);
3948 } else if (Tok.getString() == "mips64r3") {
3949 return parseSetFeature(Mips::FeatureMips64r3);
3950 } else if (Tok.getString() == "mips64r5") {
3951 return parseSetFeature(Mips::FeatureMips64r5);
3952 } else if (Tok.getString() == "mips64r6") {
3953 return parseSetFeature(Mips::FeatureMips64r6);
3954 } else if (Tok.getString() == "dsp") {
3955 return parseSetFeature(Mips::FeatureDSP);
3956 } else if (Tok.getString() == "nodsp") {
3957 return parseSetNoDspDirective();
3958 } else if (Tok.getString() == "msa") {
3959 return parseSetMsaDirective();
3960 } else if (Tok.getString() == "nomsa") {
3961 return parseSetNoMsaDirective();
3963 // It is just an identifier, look for an assignment.
3964 parseSetAssignment();
3971 /// parseDataDirective
3972 /// ::= .word [ expression (, expression)* ]
3973 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3974 MCAsmParser &Parser = getParser();
3975 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3977 const MCExpr *Value;
3978 if (getParser().parseExpression(Value))
3981 getParser().getStreamer().EmitValue(Value, Size);
3983 if (getLexer().is(AsmToken::EndOfStatement))
3986 if (getLexer().isNot(AsmToken::Comma))
3987 return Error(L, "unexpected token, expected comma");
3996 /// parseDirectiveGpWord
3997 /// ::= .gpword local_sym
3998 bool MipsAsmParser::parseDirectiveGpWord() {
3999 MCAsmParser &Parser = getParser();
4000 const MCExpr *Value;
4001 // EmitGPRel32Value requires an expression, so we are using base class
4002 // method to evaluate the expression.
4003 if (getParser().parseExpression(Value))
4005 getParser().getStreamer().EmitGPRel32Value(Value);
4007 if (getLexer().isNot(AsmToken::EndOfStatement))
4008 return Error(getLexer().getLoc(),
4009 "unexpected token, expected end of statement");
4010 Parser.Lex(); // Eat EndOfStatement token.
4014 /// parseDirectiveGpDWord
4015 /// ::= .gpdword local_sym
4016 bool MipsAsmParser::parseDirectiveGpDWord() {
4017 MCAsmParser &Parser = getParser();
4018 const MCExpr *Value;
4019 // EmitGPRel64Value requires an expression, so we are using base class
4020 // method to evaluate the expression.
4021 if (getParser().parseExpression(Value))
4023 getParser().getStreamer().EmitGPRel64Value(Value);
4025 if (getLexer().isNot(AsmToken::EndOfStatement))
4026 return Error(getLexer().getLoc(),
4027 "unexpected token, expected end of statement");
4028 Parser.Lex(); // Eat EndOfStatement token.
4032 bool MipsAsmParser::parseDirectiveOption() {
4033 MCAsmParser &Parser = getParser();
4034 // Get the option token.
4035 AsmToken Tok = Parser.getTok();
4036 // At the moment only identifiers are supported.
4037 if (Tok.isNot(AsmToken::Identifier)) {
4038 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4039 Parser.eatToEndOfStatement();
4043 StringRef Option = Tok.getIdentifier();
4045 if (Option == "pic0") {
4046 getTargetStreamer().emitDirectiveOptionPic0();
4048 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4049 Error(Parser.getTok().getLoc(),
4050 "unexpected token, expected end of statement");
4051 Parser.eatToEndOfStatement();
4056 if (Option == "pic2") {
4057 getTargetStreamer().emitDirectiveOptionPic2();
4059 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4060 Error(Parser.getTok().getLoc(),
4061 "unexpected token, expected end of statement");
4062 Parser.eatToEndOfStatement();
4068 Warning(Parser.getTok().getLoc(),
4069 "unknown option, expected 'pic0' or 'pic2'");
4070 Parser.eatToEndOfStatement();
4074 /// parseInsnDirective
4076 bool MipsAsmParser::parseInsnDirective() {
4077 // If this is not the end of the statement, report an error.
4078 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4079 reportParseError("unexpected token, expected end of statement");
4083 // The actual label marking happens in
4084 // MipsELFStreamer::createPendingLabelRelocs().
4085 getTargetStreamer().emitDirectiveInsn();
4087 getParser().Lex(); // Eat EndOfStatement token.
4091 /// parseDirectiveModule
4092 /// ::= .module oddspreg
4093 /// ::= .module nooddspreg
4094 /// ::= .module fp=value
4095 bool MipsAsmParser::parseDirectiveModule() {
4096 MCAsmParser &Parser = getParser();
4097 MCAsmLexer &Lexer = getLexer();
4098 SMLoc L = Lexer.getLoc();
4100 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4101 // TODO : get a better message.
4102 reportParseError(".module directive must appear before any code");
4107 if (Parser.parseIdentifier(Option)) {
4108 reportParseError("expected .module option identifier");
4112 if (Option == "oddspreg") {
4113 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4114 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4116 // If this is not the end of the statement, report an error.
4117 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4118 reportParseError("unexpected token, expected end of statement");
4122 return false; // parseDirectiveModule has finished successfully.
4123 } else if (Option == "nooddspreg") {
4125 Error(L, "'.module nooddspreg' requires the O32 ABI");
4129 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4130 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4132 // If this is not the end of the statement, report an error.
4133 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4134 reportParseError("unexpected token, expected end of statement");
4138 return false; // parseDirectiveModule has finished successfully.
4139 } else if (Option == "fp") {
4140 return parseDirectiveModuleFP();
4142 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4146 /// parseDirectiveModuleFP
4150 bool MipsAsmParser::parseDirectiveModuleFP() {
4151 MCAsmParser &Parser = getParser();
4152 MCAsmLexer &Lexer = getLexer();
4154 if (Lexer.isNot(AsmToken::Equal)) {
4155 reportParseError("unexpected token, expected equals sign '='");
4158 Parser.Lex(); // Eat '=' token.
4160 MipsABIFlagsSection::FpABIKind FpABI;
4161 if (!parseFpABIValue(FpABI, ".module"))
4164 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4165 reportParseError("unexpected token, expected end of statement");
4169 // Emit appropriate flags.
4170 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4171 Parser.Lex(); // Consume the EndOfStatement.
4175 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4176 StringRef Directive) {
4177 MCAsmParser &Parser = getParser();
4178 MCAsmLexer &Lexer = getLexer();
4180 if (Lexer.is(AsmToken::Identifier)) {
4181 StringRef Value = Parser.getTok().getString();
4184 if (Value != "xx") {
4185 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4190 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4194 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4198 if (Lexer.is(AsmToken::Integer)) {
4199 unsigned Value = Parser.getTok().getIntVal();
4202 if (Value != 32 && Value != 64) {
4203 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4209 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4213 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4215 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4223 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4224 MCAsmParser &Parser = getParser();
4225 StringRef IDVal = DirectiveID.getString();
4227 if (IDVal == ".cpload")
4228 return parseDirectiveCpLoad(DirectiveID.getLoc());
4229 if (IDVal == ".dword") {
4230 parseDataDirective(8, DirectiveID.getLoc());
4233 if (IDVal == ".ent") {
4234 StringRef SymbolName;
4236 if (Parser.parseIdentifier(SymbolName)) {
4237 reportParseError("expected identifier after .ent");
4241 // There's an undocumented extension that allows an integer to
4242 // follow the name of the procedure which AFAICS is ignored by GAS.
4243 // Example: .ent foo,2
4244 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4245 if (getLexer().isNot(AsmToken::Comma)) {
4246 // Even though we accept this undocumented extension for compatibility
4247 // reasons, the additional integer argument does not actually change
4248 // the behaviour of the '.ent' directive, so we would like to discourage
4249 // its use. We do this by not referring to the extended version in
4250 // error messages which are not directly related to its use.
4251 reportParseError("unexpected token, expected end of statement");
4254 Parser.Lex(); // Eat the comma.
4255 const MCExpr *DummyNumber;
4256 int64_t DummyNumberVal;
4257 // If the user was explicitly trying to use the extended version,
4258 // we still give helpful extension-related error messages.
4259 if (Parser.parseExpression(DummyNumber)) {
4260 reportParseError("expected number after comma");
4263 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4264 reportParseError("expected an absolute expression after comma");
4269 // If this is not the end of the statement, report an error.
4270 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4271 reportParseError("unexpected token, expected end of statement");
4275 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4277 getTargetStreamer().emitDirectiveEnt(*Sym);
4282 if (IDVal == ".end") {
4283 StringRef SymbolName;
4285 if (Parser.parseIdentifier(SymbolName)) {
4286 reportParseError("expected identifier after .end");
4290 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4291 reportParseError("unexpected token, expected end of statement");
4295 if (CurrentFn == nullptr) {
4296 reportParseError(".end used without .ent");
4300 if ((SymbolName != CurrentFn->getName())) {
4301 reportParseError(".end symbol does not match .ent symbol");
4305 getTargetStreamer().emitDirectiveEnd(SymbolName);
4306 CurrentFn = nullptr;
4310 if (IDVal == ".frame") {
4311 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4312 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4313 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4314 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4315 reportParseError("expected stack register");
4319 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4320 if (!StackRegOpnd.isGPRAsmReg()) {
4321 reportParseError(StackRegOpnd.getStartLoc(),
4322 "expected general purpose register");
4325 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4327 if (Parser.getTok().is(AsmToken::Comma))
4330 reportParseError("unexpected token, expected comma");
4334 // Parse the frame size.
4335 const MCExpr *FrameSize;
4336 int64_t FrameSizeVal;
4338 if (Parser.parseExpression(FrameSize)) {
4339 reportParseError("expected frame size value");
4343 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4344 reportParseError("frame size not an absolute expression");
4348 if (Parser.getTok().is(AsmToken::Comma))
4351 reportParseError("unexpected token, expected comma");
4355 // Parse the return register.
4357 ResTy = parseAnyRegister(TmpReg);
4358 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4359 reportParseError("expected return register");
4363 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4364 if (!ReturnRegOpnd.isGPRAsmReg()) {
4365 reportParseError(ReturnRegOpnd.getStartLoc(),
4366 "expected general purpose register");
4370 // If this is not the end of the statement, report an error.
4371 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4372 reportParseError("unexpected token, expected end of statement");
4376 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4377 ReturnRegOpnd.getGPR32Reg());
4381 if (IDVal == ".set") {
4382 return parseDirectiveSet();
4385 if (IDVal == ".mask" || IDVal == ".fmask") {
4386 // .mask bitmask, frame_offset
4387 // bitmask: One bit for each register used.
4388 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4389 // first register is expected to be saved.
4391 // .mask 0x80000000, -4
4392 // .fmask 0x80000000, -4
4395 // Parse the bitmask
4396 const MCExpr *BitMask;
4399 if (Parser.parseExpression(BitMask)) {
4400 reportParseError("expected bitmask value");
4404 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4405 reportParseError("bitmask not an absolute expression");
4409 if (Parser.getTok().is(AsmToken::Comma))
4412 reportParseError("unexpected token, expected comma");
4416 // Parse the frame_offset
4417 const MCExpr *FrameOffset;
4418 int64_t FrameOffsetVal;
4420 if (Parser.parseExpression(FrameOffset)) {
4421 reportParseError("expected frame offset value");
4425 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4426 reportParseError("frame offset not an absolute expression");
4430 // If this is not the end of the statement, report an error.
4431 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4432 reportParseError("unexpected token, expected end of statement");
4436 if (IDVal == ".mask")
4437 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4439 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4443 if (IDVal == ".nan")
4444 return parseDirectiveNaN();
4446 if (IDVal == ".gpword") {
4447 parseDirectiveGpWord();
4451 if (IDVal == ".gpdword") {
4452 parseDirectiveGpDWord();
4456 if (IDVal == ".word") {
4457 parseDataDirective(4, DirectiveID.getLoc());
4461 if (IDVal == ".option")
4462 return parseDirectiveOption();
4464 if (IDVal == ".abicalls") {
4465 getTargetStreamer().emitDirectiveAbiCalls();
4466 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4467 Error(Parser.getTok().getLoc(),
4468 "unexpected token, expected end of statement");
4470 Parser.eatToEndOfStatement();
4475 if (IDVal == ".cpsetup")
4476 return parseDirectiveCPSetup();
4478 if (IDVal == ".module")
4479 return parseDirectiveModule();
4481 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4482 return parseInternalDirectiveReallowModule();
4484 if (IDVal == ".insn")
4485 return parseInsnDirective();
4490 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4491 // If this is not the end of the statement, report an error.
4492 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4493 reportParseError("unexpected token, expected end of statement");
4497 getTargetStreamer().reallowModuleDirective();
4499 getParser().Lex(); // Eat EndOfStatement token.
4503 extern "C" void LLVMInitializeMipsAsmParser() {
4504 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4505 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4506 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4507 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4510 #define GET_REGISTER_MATCHER
4511 #define GET_MATCHER_IMPLEMENTATION
4512 #include "MipsGenAsmMatcher.inc"