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->getATRegNum();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegNum() const { return ATReg; }
57 bool setATReg(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 uint64_t getFeatures() const { return Features; }
74 void setFeatures(uint64_t Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const uint64_t AllArchRelatedMask =
82 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
83 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
84 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
85 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
86 Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
87 Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
88 Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
89 Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
100 class MipsAsmParser : public MCTargetAsmParser {
101 MipsTargetStreamer &getTargetStreamer() {
102 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
103 return static_cast<MipsTargetStreamer &>(TS);
106 MCSubtargetInfo &STI;
108 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
109 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
110 // nullptr, which indicates that no function is currently
111 // selected. This usually happens after an '.end func'
114 // Print a warning along with its fix-it message at the given range.
115 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
116 SMRange Range, bool ShowColors = true);
118 #define GET_ASSEMBLER_HEADER
119 #include "MipsGenAsmMatcher.inc"
121 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
123 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
124 OperandVector &Operands, MCStreamer &Out,
126 bool MatchingInlineAsm) override;
128 /// Parse a register as used in CFI directives
129 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
131 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
133 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
135 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
136 SMLoc NameLoc, OperandVector &Operands) override;
138 bool ParseDirective(AsmToken DirectiveID) override;
140 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
142 MipsAsmParser::OperandMatchResultTy
143 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
144 StringRef Identifier, SMLoc S);
146 MipsAsmParser::OperandMatchResultTy
147 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
151 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
153 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy
160 parseRegisterPair (OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseMovePRegPair(OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseRegisterList (OperandVector &Operands);
168 bool searchSymbolAlias(OperandVector &Operands);
170 bool parseOperand(OperandVector &, StringRef Mnemonic);
172 bool needsExpansion(MCInst &Inst);
174 // Expands assembly pseudo instructions.
175 // Returns false on success, true otherwise.
176 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
190 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
200 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
203 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 bool reportParseError(Twine ErrorMsg);
207 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
209 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
210 bool parseRelocOperand(const MCExpr *&Res);
212 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
214 bool isEvaluated(const MCExpr *Expr);
215 bool parseSetMips0Directive();
216 bool parseSetArchDirective();
217 bool parseSetFeature(uint64_t Feature);
218 bool parseDirectiveCpLoad(SMLoc Loc);
219 bool parseDirectiveCPSetup();
220 bool parseDirectiveNaN();
221 bool parseDirectiveSet();
222 bool parseDirectiveOption();
223 bool parseInsnDirective();
225 bool parseSetAtDirective();
226 bool parseSetNoAtDirective();
227 bool parseSetMacroDirective();
228 bool parseSetNoMacroDirective();
229 bool parseSetMsaDirective();
230 bool parseSetNoMsaDirective();
231 bool parseSetNoDspDirective();
232 bool parseSetReorderDirective();
233 bool parseSetNoReorderDirective();
234 bool parseSetMips16Directive();
235 bool parseSetNoMips16Directive();
236 bool parseSetFpDirective();
237 bool parseSetPopDirective();
238 bool parseSetPushDirective();
240 bool parseSetAssignment();
242 bool parseDataDirective(unsigned Size, SMLoc L);
243 bool parseDirectiveGpWord();
244 bool parseDirectiveGpDWord();
245 bool parseDirectiveModule();
246 bool parseDirectiveModuleFP();
247 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
248 StringRef Directive);
250 bool parseInternalDirectiveReallowModule();
252 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
254 bool eatComma(StringRef ErrorStr);
256 int matchCPURegisterName(StringRef Symbol);
258 int matchHWRegsRegisterName(StringRef Symbol);
260 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
262 int matchFPURegisterName(StringRef Name);
264 int matchFCCRegisterName(StringRef Name);
266 int matchACRegisterName(StringRef Name);
268 int matchMSA128RegisterName(StringRef Name);
270 int matchMSA128CtrlRegisterName(StringRef Name);
272 unsigned getReg(int RC, int RegNo);
274 unsigned getGPR(int RegNo);
276 /// Returns the internal register number for the current AT. Also checks if
277 /// the current AT is unavailable (set to $0) and gives an error if it is.
278 /// This should be used in pseudo-instruction expansions which need AT.
279 unsigned getATReg(SMLoc Loc);
281 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
282 SmallVectorImpl<MCInst> &Instructions);
284 // Helper function that checks if the value of a vector index is within the
285 // boundaries of accepted values for each RegisterKind
286 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
287 bool validateMSAIndex(int Val, int RegKind);
289 // Selects a new architecture by updating the FeatureBits with the necessary
290 // info including implied dependencies.
291 // Internally, it clears all the feature bits related to *any* architecture
292 // and selects the new one using the ToggleFeature functionality of the
293 // MCSubtargetInfo object that handles implied dependencies. The reason we
294 // clear all the arch related bits manually is because ToggleFeature only
295 // clears the features that imply the feature being cleared and not the
296 // features implied by the feature being cleared. This is easier to see
298 // --------------------------------------------------
299 // | Feature | Implies |
300 // | -------------------------------------------------|
301 // | FeatureMips1 | None |
302 // | FeatureMips2 | FeatureMips1 |
303 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
304 // | FeatureMips4 | FeatureMips3 |
306 // --------------------------------------------------
308 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
309 // FeatureMipsGP64 | FeatureMips1)
310 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
311 void selectArch(StringRef ArchFeature) {
312 uint64_t FeatureBits = STI.getFeatureBits();
313 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
314 STI.setFeatureBits(FeatureBits);
315 setAvailableFeatures(
316 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
317 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
320 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
321 if (!(STI.getFeatureBits() & Feature)) {
322 setAvailableFeatures(
323 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
325 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
328 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
329 if (STI.getFeatureBits() & Feature) {
330 setAvailableFeatures(
331 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
333 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
337 enum MipsMatchResultTy {
338 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
339 #define GET_OPERAND_DIAGNOSTIC_TYPES
340 #include "MipsGenAsmMatcher.inc"
341 #undef GET_OPERAND_DIAGNOSTIC_TYPES
345 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
346 const MCInstrInfo &MII, const MCTargetOptions &Options)
347 : MCTargetAsmParser(), STI(sti),
348 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
349 sti.getCPU(), Options)) {
350 MCAsmParserExtension::Initialize(parser);
352 parser.addAliasForDirective(".asciiz", ".asciz");
354 // Initialize the set of available features.
355 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
357 // Remember the initial assembler options. The user can not modify these.
358 AssemblerOptions.push_back(
359 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
361 // Create an assembler options environment for the user to modify.
362 AssemblerOptions.push_back(
363 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
365 getTargetStreamer().updateABIInfo(*this);
367 if (!isABI_O32() && !useOddSPReg() != 0)
368 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
373 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
374 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
376 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
377 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
378 const MipsABIInfo &getABI() const { return ABI; }
379 bool isABI_N32() const { return ABI.IsN32(); }
380 bool isABI_N64() const { return ABI.IsN64(); }
381 bool isABI_O32() const { return ABI.IsO32(); }
382 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
384 bool useOddSPReg() const {
385 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
388 bool inMicroMipsMode() const {
389 return STI.getFeatureBits() & Mips::FeatureMicroMips;
391 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
392 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
393 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
394 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
395 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
396 bool hasMips32() const {
397 return (STI.getFeatureBits() & Mips::FeatureMips32);
399 bool hasMips64() const {
400 return (STI.getFeatureBits() & Mips::FeatureMips64);
402 bool hasMips32r2() const {
403 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
405 bool hasMips64r2() const {
406 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
408 bool hasMips32r3() const {
409 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
411 bool hasMips64r3() const {
412 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
414 bool hasMips32r5() const {
415 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
417 bool hasMips64r5() const {
418 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
420 bool hasMips32r6() const {
421 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
423 bool hasMips64r6() const {
424 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
426 bool hasCnMips() const {
427 return (STI.getFeatureBits() & Mips::FeatureCnMips);
429 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
430 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
431 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
433 bool inMips16Mode() const {
434 return STI.getFeatureBits() & Mips::FeatureMips16;
436 // TODO: see how can we get this info.
437 bool abiUsesSoftFloat() const { return false; }
439 /// Warn if RegNo is the current assembler temporary.
440 void warnIfAssemblerTemporary(int RegNo, 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.warnIfAssemblerTemporary(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 this instruction has a delay slot and .set reorder is active,
1387 // emit a NOP after it.
1388 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1389 Instructions.push_back(Inst);
1390 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1394 if (MCID.mayLoad() || MCID.mayStore()) {
1395 // Check the offset of memory operand, if it is a symbol
1396 // reference or immediate we may have to expand instructions.
1397 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1398 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1399 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1400 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1401 MCOperand &Op = Inst.getOperand(i);
1403 int MemOffset = Op.getImm();
1404 if (MemOffset < -32768 || MemOffset > 32767) {
1405 // Offset can't exceed 16bit value.
1406 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1409 } else if (Op.isExpr()) {
1410 const MCExpr *Expr = Op.getExpr();
1411 if (Expr->getKind() == MCExpr::SymbolRef) {
1412 const MCSymbolRefExpr *SR =
1413 static_cast<const MCSymbolRefExpr *>(Expr);
1414 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1416 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1419 } else if (!isEvaluated(Expr)) {
1420 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1428 if (inMicroMipsMode()) {
1429 if (MCID.mayLoad()) {
1430 // Try to create 16-bit GP relative load instruction.
1431 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1432 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1433 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1434 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1435 MCOperand &Op = Inst.getOperand(i);
1437 int MemOffset = Op.getImm();
1438 MCOperand &DstReg = Inst.getOperand(0);
1439 MCOperand &BaseReg = Inst.getOperand(1);
1440 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1441 getContext().getRegisterInfo()->getRegClass(
1442 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1443 BaseReg.getReg() == Mips::GP) {
1445 TmpInst.setLoc(IDLoc);
1446 TmpInst.setOpcode(Mips::LWGP_MM);
1447 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1448 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1449 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1450 Instructions.push_back(TmpInst);
1458 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1463 switch (Inst.getOpcode()) {
1466 case Mips::ADDIUS5_MM:
1467 Opnd = Inst.getOperand(2);
1469 return Error(IDLoc, "expected immediate operand kind");
1470 Imm = Opnd.getImm();
1471 if (Imm < -8 || Imm > 7)
1472 return Error(IDLoc, "immediate operand value out of range");
1474 case Mips::ADDIUSP_MM:
1475 Opnd = Inst.getOperand(0);
1477 return Error(IDLoc, "expected immediate operand kind");
1478 Imm = Opnd.getImm();
1479 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1481 return Error(IDLoc, "immediate operand value out of range");
1483 case Mips::SLL16_MM:
1484 case Mips::SRL16_MM:
1485 Opnd = Inst.getOperand(2);
1487 return Error(IDLoc, "expected immediate operand kind");
1488 Imm = Opnd.getImm();
1489 if (Imm < 1 || Imm > 8)
1490 return Error(IDLoc, "immediate operand value out of range");
1493 Opnd = Inst.getOperand(1);
1495 return Error(IDLoc, "expected immediate operand kind");
1496 Imm = Opnd.getImm();
1497 if (Imm < -1 || Imm > 126)
1498 return Error(IDLoc, "immediate operand value out of range");
1500 case Mips::ADDIUR2_MM:
1501 Opnd = Inst.getOperand(2);
1503 return Error(IDLoc, "expected immediate operand kind");
1504 Imm = Opnd.getImm();
1505 if (!(Imm == 1 || Imm == -1 ||
1506 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1507 return Error(IDLoc, "immediate operand value out of range");
1509 case Mips::ADDIUR1SP_MM:
1510 Opnd = Inst.getOperand(1);
1512 return Error(IDLoc, "expected immediate operand kind");
1513 Imm = Opnd.getImm();
1514 if (OffsetToAlignment(Imm, 4LL))
1515 return Error(IDLoc, "misaligned immediate operand value");
1516 if (Imm < 0 || Imm > 255)
1517 return Error(IDLoc, "immediate operand value out of range");
1519 case Mips::ANDI16_MM:
1520 Opnd = Inst.getOperand(2);
1522 return Error(IDLoc, "expected immediate operand kind");
1523 Imm = Opnd.getImm();
1524 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1525 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1526 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1527 return Error(IDLoc, "immediate operand value out of range");
1529 case Mips::LBU16_MM:
1530 Opnd = Inst.getOperand(2);
1532 return Error(IDLoc, "expected immediate operand kind");
1533 Imm = Opnd.getImm();
1534 if (Imm < -1 || Imm > 14)
1535 return Error(IDLoc, "immediate operand value out of range");
1538 Opnd = Inst.getOperand(2);
1540 return Error(IDLoc, "expected immediate operand kind");
1541 Imm = Opnd.getImm();
1542 if (Imm < 0 || Imm > 15)
1543 return Error(IDLoc, "immediate operand value out of range");
1545 case Mips::LHU16_MM:
1547 Opnd = Inst.getOperand(2);
1549 return Error(IDLoc, "expected immediate operand kind");
1550 Imm = Opnd.getImm();
1551 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1552 return Error(IDLoc, "immediate operand value out of range");
1556 Opnd = Inst.getOperand(2);
1558 return Error(IDLoc, "expected immediate operand kind");
1559 Imm = Opnd.getImm();
1560 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1561 return Error(IDLoc, "immediate operand value out of range");
1565 Opnd = Inst.getOperand(2);
1567 return Error(IDLoc, "expected immediate operand kind");
1568 Imm = Opnd.getImm();
1569 if (!isUInt<5>(Imm))
1570 return Error(IDLoc, "immediate operand value out of range");
1572 case Mips::ADDIUPC_MM:
1573 MCOperand Opnd = Inst.getOperand(1);
1575 return Error(IDLoc, "expected immediate operand kind");
1576 int Imm = Opnd.getImm();
1577 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1578 return Error(IDLoc, "immediate operand value out of range");
1583 if (needsExpansion(Inst))
1584 return expandInstruction(Inst, IDLoc, Instructions);
1586 Instructions.push_back(Inst);
1591 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1593 switch (Inst.getOpcode()) {
1594 case Mips::LoadImm32:
1595 case Mips::LoadImm64:
1596 case Mips::LoadAddrImm32:
1597 case Mips::LoadAddrReg32:
1598 case Mips::B_MM_Pseudo:
1601 case Mips::JalOneReg:
1602 case Mips::JalTwoReg:
1609 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1610 SmallVectorImpl<MCInst> &Instructions) {
1611 switch (Inst.getOpcode()) {
1612 default: llvm_unreachable("unimplemented expansion");
1613 case Mips::LoadImm32:
1614 return expandLoadImm(Inst, IDLoc, Instructions);
1615 case Mips::LoadImm64:
1617 Error(IDLoc, "instruction requires a 64-bit architecture");
1620 return expandLoadImm(Inst, IDLoc, Instructions);
1621 case Mips::LoadAddrImm32:
1622 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1623 case Mips::LoadAddrReg32:
1624 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1625 case Mips::B_MM_Pseudo:
1626 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1629 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1630 case Mips::JalOneReg:
1631 case Mips::JalTwoReg:
1632 return expandJalWithRegs(Inst, IDLoc, Instructions);
1637 template <bool PerformShift>
1638 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1639 SmallVectorImpl<MCInst> &Instructions) {
1642 tmpInst.setOpcode(Mips::DSLL);
1643 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1644 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1645 tmpInst.addOperand(MCOperand::CreateImm(16));
1646 tmpInst.setLoc(IDLoc);
1647 Instructions.push_back(tmpInst);
1650 tmpInst.setOpcode(Mips::ORi);
1651 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1652 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1653 tmpInst.addOperand(Operand);
1654 tmpInst.setLoc(IDLoc);
1655 Instructions.push_back(tmpInst);
1658 template <int Shift, bool PerformShift>
1659 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1660 SmallVectorImpl<MCInst> &Instructions) {
1661 createShiftOr<PerformShift>(
1662 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1663 IDLoc, Instructions);
1667 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1668 SmallVectorImpl<MCInst> &Instructions) {
1669 // Create a JALR instruction which is going to replace the pseudo-JAL.
1671 JalrInst.setLoc(IDLoc);
1672 const MCOperand FirstRegOp = Inst.getOperand(0);
1673 const unsigned Opcode = Inst.getOpcode();
1675 if (Opcode == Mips::JalOneReg) {
1676 // jal $rs => jalr $rs
1677 if (inMicroMipsMode()) {
1678 JalrInst.setOpcode(Mips::JALR16_MM);
1679 JalrInst.addOperand(FirstRegOp);
1681 JalrInst.setOpcode(Mips::JALR);
1682 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1683 JalrInst.addOperand(FirstRegOp);
1685 } else if (Opcode == Mips::JalTwoReg) {
1686 // jal $rd, $rs => jalr $rd, $rs
1687 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1688 JalrInst.addOperand(FirstRegOp);
1689 const MCOperand SecondRegOp = Inst.getOperand(1);
1690 JalrInst.addOperand(SecondRegOp);
1692 Instructions.push_back(JalrInst);
1694 // If .set reorder is active, emit a NOP after it.
1695 if (AssemblerOptions.back()->isReorder()) {
1696 // This is a 32-bit NOP because these 2 pseudo-instructions
1697 // do not have a short delay slot.
1699 NopInst.setOpcode(Mips::SLL);
1700 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1701 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1702 NopInst.addOperand(MCOperand::CreateImm(0));
1703 Instructions.push_back(NopInst);
1709 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1710 SmallVectorImpl<MCInst> &Instructions) {
1712 const MCOperand &ImmOp = Inst.getOperand(1);
1713 assert(ImmOp.isImm() && "expected immediate operand kind");
1714 const MCOperand &RegOp = Inst.getOperand(0);
1715 assert(RegOp.isReg() && "expected register operand kind");
1717 int64_t ImmValue = ImmOp.getImm();
1718 tmpInst.setLoc(IDLoc);
1719 // FIXME: gas has a special case for values that are 000...1111, which
1720 // becomes a li -1 and then a dsrl
1721 if (0 <= ImmValue && ImmValue <= 65535) {
1722 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1723 // li d,j => ori d,$zero,j
1724 tmpInst.setOpcode(Mips::ORi);
1725 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1726 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1727 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1728 Instructions.push_back(tmpInst);
1729 } else if (ImmValue < 0 && ImmValue >= -32768) {
1730 // For negative signed 16-bit values (-32768 <= j < 0):
1731 // li d,j => addiu d,$zero,j
1732 tmpInst.setOpcode(Mips::ADDiu);
1733 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1734 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1735 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1736 Instructions.push_back(tmpInst);
1737 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1738 // For all other values which are representable as a 32-bit integer:
1739 // li d,j => lui d,hi16(j)
1741 tmpInst.setOpcode(Mips::LUi);
1742 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1743 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1744 Instructions.push_back(tmpInst);
1745 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1746 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1748 Error(IDLoc, "instruction requires a 64-bit architecture");
1752 // <------- lo32 ------>
1753 // <------- hi32 ------>
1754 // <- hi16 -> <- lo16 ->
1755 // _________________________________
1757 // | 16-bytes | 16-bytes | 16-bytes |
1758 // |__________|__________|__________|
1760 // For any 64-bit value that is representable as a 48-bit integer:
1761 // li d,j => lui d,hi16(j)
1762 // ori d,d,hi16(lo32(j))
1764 // ori d,d,lo16(lo32(j))
1765 tmpInst.setOpcode(Mips::LUi);
1766 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1768 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1769 Instructions.push_back(tmpInst);
1770 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1771 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1774 Error(IDLoc, "instruction requires a 64-bit architecture");
1778 // <------- hi32 ------> <------- lo32 ------>
1779 // <- hi16 -> <- lo16 ->
1780 // ___________________________________________
1782 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1783 // |__________|__________|__________|__________|
1785 // For all other values which are representable as a 64-bit integer:
1786 // li d,j => lui d,hi16(j)
1787 // ori d,d,lo16(hi32(j))
1789 // ori d,d,hi16(lo32(j))
1791 // ori d,d,lo16(lo32(j))
1792 tmpInst.setOpcode(Mips::LUi);
1793 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1795 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1796 Instructions.push_back(tmpInst);
1797 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1798 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1799 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1805 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1806 SmallVectorImpl<MCInst> &Instructions) {
1808 const MCOperand &ImmOp = Inst.getOperand(2);
1809 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1810 "expected immediate operand kind");
1811 if (!ImmOp.isImm()) {
1812 expandLoadAddressSym(Inst, IDLoc, Instructions);
1815 const MCOperand &SrcRegOp = Inst.getOperand(1);
1816 assert(SrcRegOp.isReg() && "expected register operand kind");
1817 const MCOperand &DstRegOp = Inst.getOperand(0);
1818 assert(DstRegOp.isReg() && "expected register operand kind");
1819 int ImmValue = ImmOp.getImm();
1820 if (-32768 <= ImmValue && ImmValue <= 65535) {
1821 // For -32768 <= j <= 65535.
1822 // la d,j(s) => addiu d,s,j
1823 tmpInst.setOpcode(Mips::ADDiu);
1824 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1825 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1826 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1827 Instructions.push_back(tmpInst);
1829 // For any other value of j that is representable as a 32-bit integer.
1830 // la d,j(s) => lui d,hi16(j)
1833 tmpInst.setOpcode(Mips::LUi);
1834 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1835 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1836 Instructions.push_back(tmpInst);
1838 tmpInst.setOpcode(Mips::ORi);
1839 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1840 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1841 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1842 Instructions.push_back(tmpInst);
1844 tmpInst.setOpcode(Mips::ADDu);
1845 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1846 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1847 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1848 Instructions.push_back(tmpInst);
1854 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1855 SmallVectorImpl<MCInst> &Instructions) {
1857 const MCOperand &ImmOp = Inst.getOperand(1);
1858 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1859 "expected immediate operand kind");
1860 if (!ImmOp.isImm()) {
1861 expandLoadAddressSym(Inst, IDLoc, Instructions);
1864 const MCOperand &RegOp = Inst.getOperand(0);
1865 assert(RegOp.isReg() && "expected register operand kind");
1866 int ImmValue = ImmOp.getImm();
1867 if (-32768 <= ImmValue && ImmValue <= 65535) {
1868 // For -32768 <= j <= 65535.
1869 // la d,j => addiu d,$zero,j
1870 tmpInst.setOpcode(Mips::ADDiu);
1871 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1872 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1873 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1874 Instructions.push_back(tmpInst);
1876 // For any other value of j that is representable as a 32-bit integer.
1877 // la d,j => lui d,hi16(j)
1879 tmpInst.setOpcode(Mips::LUi);
1880 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1881 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1882 Instructions.push_back(tmpInst);
1884 tmpInst.setOpcode(Mips::ORi);
1885 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1886 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1887 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1888 Instructions.push_back(tmpInst);
1894 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1895 SmallVectorImpl<MCInst> &Instructions) {
1896 // FIXME: If we do have a valid at register to use, we should generate a
1897 // slightly shorter sequence here.
1899 int ExprOperandNo = 1;
1900 // Sometimes the assembly parser will get the immediate expression as
1901 // a $zero + an immediate.
1902 if (Inst.getNumOperands() == 3) {
1903 assert(Inst.getOperand(1).getReg() ==
1904 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1907 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1908 assert(SymOp.isExpr() && "expected symbol operand kind");
1909 const MCOperand &RegOp = Inst.getOperand(0);
1910 unsigned RegNo = RegOp.getReg();
1911 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1912 const MCSymbolRefExpr *HiExpr =
1913 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1914 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1915 const MCSymbolRefExpr *LoExpr =
1916 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1917 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1919 // If it's a 64-bit architecture, expand to:
1920 // la d,sym => lui d,highest(sym)
1921 // ori d,d,higher(sym)
1923 // ori d,d,hi16(sym)
1925 // ori d,d,lo16(sym)
1926 const MCSymbolRefExpr *HighestExpr =
1927 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1928 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1929 const MCSymbolRefExpr *HigherExpr =
1930 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1931 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1933 tmpInst.setOpcode(Mips::LUi);
1934 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1935 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1936 Instructions.push_back(tmpInst);
1938 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1940 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1942 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1945 // Otherwise, expand to:
1946 // la d,sym => lui d,hi16(sym)
1947 // ori d,d,lo16(sym)
1948 tmpInst.setOpcode(Mips::LUi);
1949 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1950 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1951 Instructions.push_back(tmpInst);
1953 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1958 bool MipsAsmParser::expandUncondBranchMMPseudo(
1959 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1960 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1961 "unexpected number of operands");
1963 MCOperand Offset = Inst.getOperand(0);
1964 if (Offset.isExpr()) {
1966 Inst.setOpcode(Mips::BEQ_MM);
1967 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1968 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1969 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1971 assert(Offset.isImm() && "expected immediate operand kind");
1972 if (isIntN(11, Offset.getImm())) {
1973 // If offset fits into 11 bits then this instruction becomes microMIPS
1974 // 16-bit unconditional branch instruction.
1975 Inst.setOpcode(Mips::B16_MM);
1977 if (!isIntN(17, Offset.getImm()))
1978 Error(IDLoc, "branch target out of range");
1979 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1980 Error(IDLoc, "branch to misaligned address");
1982 Inst.setOpcode(Mips::BEQ_MM);
1983 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1984 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1985 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1988 Instructions.push_back(Inst);
1990 // If .set reorder is active, emit a NOP after the branch instruction.
1991 if (AssemblerOptions.back()->isReorder())
1992 createNop(true, IDLoc, Instructions);
1997 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1998 SmallVectorImpl<MCInst> &Instructions,
1999 bool isLoad, bool isImmOpnd) {
2000 const MCSymbolRefExpr *SR;
2002 unsigned ImmOffset, HiOffset, LoOffset;
2003 const MCExpr *ExprOffset;
2005 // 1st operand is either the source or destination register.
2006 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2007 unsigned RegOpNum = Inst.getOperand(0).getReg();
2008 // 2nd operand is the base register.
2009 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2010 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2011 // 3rd operand is either an immediate or expression.
2013 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2014 ImmOffset = Inst.getOperand(2).getImm();
2015 LoOffset = ImmOffset & 0x0000ffff;
2016 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2017 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2018 if (LoOffset & 0x8000)
2021 ExprOffset = Inst.getOperand(2).getExpr();
2022 // All instructions will have the same location.
2023 TempInst.setLoc(IDLoc);
2024 // These are some of the types of expansions we perform here:
2025 // 1) lw $8, sym => lui $8, %hi(sym)
2026 // lw $8, %lo(sym)($8)
2027 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2029 // lw $8, %lo(offset)($9)
2030 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2032 // lw $8, %lo(offset)($at)
2033 // 4) sw $8, sym => lui $at, %hi(sym)
2034 // sw $8, %lo(sym)($at)
2035 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2037 // sw $8, %lo(offset)($at)
2038 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2039 // ldc1 $f0, %lo(sym)($at)
2041 // For load instructions we can use the destination register as a temporary
2042 // if base and dst are different (examples 1 and 2) and if the base register
2043 // is general purpose otherwise we must use $at (example 6) and error if it's
2044 // not available. For stores we must use $at (examples 4 and 5) because we
2045 // must not clobber the source register setting up the offset.
2046 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2047 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2048 unsigned RegClassIDOp0 =
2049 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2050 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2051 (RegClassIDOp0 == Mips::GPR64RegClassID);
2052 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2053 TmpRegNum = RegOpNum;
2055 // At this point we need AT to perform the expansions and we exit if it is
2057 TmpRegNum = getATReg(IDLoc);
2062 TempInst.setOpcode(Mips::LUi);
2063 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2065 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2067 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2068 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2069 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2070 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2072 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2074 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2075 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2078 // Add the instruction to the list.
2079 Instructions.push_back(TempInst);
2080 // Prepare TempInst for next instruction.
2082 // Add temp register to base.
2083 if (BaseRegNum != Mips::ZERO) {
2084 TempInst.setOpcode(Mips::ADDu);
2085 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2086 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2087 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2088 Instructions.push_back(TempInst);
2091 // And finally, create original instruction with low part
2092 // of offset and new base.
2093 TempInst.setOpcode(Inst.getOpcode());
2094 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2095 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2097 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2099 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2100 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2101 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2103 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2105 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2106 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2109 Instructions.push_back(TempInst);
2114 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2115 SmallVectorImpl<MCInst> &Instructions) {
2116 unsigned OpNum = Inst.getNumOperands();
2117 unsigned Opcode = Inst.getOpcode();
2118 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2120 assert (Inst.getOperand(OpNum - 1).isImm() &&
2121 Inst.getOperand(OpNum - 2).isReg() &&
2122 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2124 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2125 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2126 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2127 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2128 // It can be implemented as SWM16 or LWM16 instruction.
2129 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2131 Inst.setOpcode(NewOpcode);
2132 Instructions.push_back(Inst);
2136 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2137 SmallVectorImpl<MCInst> &Instructions) {
2139 if (hasShortDelaySlot) {
2140 NopInst.setOpcode(Mips::MOVE16_MM);
2141 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2142 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2144 NopInst.setOpcode(Mips::SLL);
2145 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2146 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2147 NopInst.addOperand(MCOperand::CreateImm(0));
2149 Instructions.push_back(NopInst);
2152 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2153 // As described by the Mips32r2 spec, the registers Rd and Rs for
2154 // jalr.hb must be different.
2155 unsigned Opcode = Inst.getOpcode();
2157 if (Opcode == Mips::JALR_HB &&
2158 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2159 return Match_RequiresDifferentSrcAndDst;
2161 return Match_Success;
2164 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2165 OperandVector &Operands,
2167 uint64_t &ErrorInfo,
2168 bool MatchingInlineAsm) {
2171 SmallVector<MCInst, 8> Instructions;
2172 unsigned MatchResult =
2173 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2175 switch (MatchResult) {
2176 case Match_Success: {
2177 if (processInstruction(Inst, IDLoc, Instructions))
2179 for (unsigned i = 0; i < Instructions.size(); i++)
2180 Out.EmitInstruction(Instructions[i], STI);
2183 case Match_MissingFeature:
2184 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2186 case Match_InvalidOperand: {
2187 SMLoc ErrorLoc = IDLoc;
2188 if (ErrorInfo != ~0ULL) {
2189 if (ErrorInfo >= Operands.size())
2190 return Error(IDLoc, "too few operands for instruction");
2192 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2193 if (ErrorLoc == SMLoc())
2197 return Error(ErrorLoc, "invalid operand for instruction");
2199 case Match_MnemonicFail:
2200 return Error(IDLoc, "invalid instruction");
2201 case Match_RequiresDifferentSrcAndDst:
2202 return Error(IDLoc, "source and destination must be different");
2205 llvm_unreachable("Implement any new match types added!");
2208 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
2209 if ((RegIndex != 0) &&
2210 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
2212 Warning(Loc, "used $at without \".set noat\"");
2214 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
2215 Twine(RegIndex) + "\"");
2220 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2221 SMRange Range, bool ShowColors) {
2222 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2223 Range, SMFixIt(Range, FixMsg),
2227 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2230 CC = StringSwitch<unsigned>(Name)
2266 if (!(isABI_N32() || isABI_N64()))
2269 if (12 <= CC && CC <= 15) {
2270 // Name is one of t4-t7
2271 AsmToken RegTok = getLexer().peekTok();
2272 SMRange RegRange = RegTok.getLocRange();
2274 StringRef FixedName = StringSwitch<StringRef>(Name)
2280 assert(FixedName != "" && "Register name is not one of t4-t7.");
2282 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2283 "Did you mean $" + FixedName + "?", RegRange);
2286 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2287 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2288 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2289 if (8 <= CC && CC <= 11)
2293 CC = StringSwitch<unsigned>(Name)
2305 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2308 CC = StringSwitch<unsigned>(Name)
2309 .Case("hwr_cpunum", 0)
2310 .Case("hwr_synci_step", 1)
2312 .Case("hwr_ccres", 3)
2313 .Case("hwr_ulr", 29)
2319 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2321 if (Name[0] == 'f') {
2322 StringRef NumString = Name.substr(1);
2324 if (NumString.getAsInteger(10, IntVal))
2325 return -1; // This is not an integer.
2326 if (IntVal > 31) // Maximum index for fpu register.
2333 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2335 if (Name.startswith("fcc")) {
2336 StringRef NumString = Name.substr(3);
2338 if (NumString.getAsInteger(10, IntVal))
2339 return -1; // This is not an integer.
2340 if (IntVal > 7) // There are only 8 fcc registers.
2347 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2349 if (Name.startswith("ac")) {
2350 StringRef NumString = Name.substr(2);
2352 if (NumString.getAsInteger(10, IntVal))
2353 return -1; // This is not an integer.
2354 if (IntVal > 3) // There are only 3 acc registers.
2361 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2364 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2373 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2376 CC = StringSwitch<unsigned>(Name)
2379 .Case("msaaccess", 2)
2381 .Case("msamodify", 4)
2382 .Case("msarequest", 5)
2384 .Case("msaunmap", 7)
2390 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2391 unsigned ATIndex = AssemblerOptions.back()->getATRegNum();
2393 reportParseError(Loc,
2394 "pseudo-instruction requires $at, which is not available");
2397 unsigned AT = getReg(
2398 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2402 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2403 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2406 unsigned MipsAsmParser::getGPR(int RegNo) {
2407 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2411 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2413 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2416 return getReg(RegClass, RegNum);
2419 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2420 MCAsmParser &Parser = getParser();
2421 DEBUG(dbgs() << "parseOperand\n");
2423 // Check if the current operand has a custom associated parser, if so, try to
2424 // custom parse the operand, or fallback to the general approach.
2425 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2426 if (ResTy == MatchOperand_Success)
2428 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2429 // there was a match, but an error occurred, in which case, just return that
2430 // the operand parsing failed.
2431 if (ResTy == MatchOperand_ParseFail)
2434 DEBUG(dbgs() << ".. Generic Parser\n");
2436 switch (getLexer().getKind()) {
2438 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2440 case AsmToken::Dollar: {
2441 // Parse the register.
2442 SMLoc S = Parser.getTok().getLoc();
2444 // Almost all registers have been parsed by custom parsers. There is only
2445 // one exception to this. $zero (and it's alias $0) will reach this point
2446 // for div, divu, and similar instructions because it is not an operand
2447 // to the instruction definition but an explicit register. Special case
2448 // this situation for now.
2449 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2452 // Maybe it is a symbol reference.
2453 StringRef Identifier;
2454 if (Parser.parseIdentifier(Identifier))
2457 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2458 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2459 // Otherwise create a symbol reference.
2461 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2463 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2466 // Else drop to expression parsing.
2467 case AsmToken::LParen:
2468 case AsmToken::Minus:
2469 case AsmToken::Plus:
2470 case AsmToken::Integer:
2471 case AsmToken::Tilde:
2472 case AsmToken::String: {
2473 DEBUG(dbgs() << ".. generic integer\n");
2474 OperandMatchResultTy ResTy = parseImm(Operands);
2475 return ResTy != MatchOperand_Success;
2477 case AsmToken::Percent: {
2478 // It is a symbol reference or constant expression.
2479 const MCExpr *IdVal;
2480 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2481 if (parseRelocOperand(IdVal))
2484 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2486 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2488 } // case AsmToken::Percent
2489 } // switch(getLexer().getKind())
2493 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2494 StringRef RelocStr) {
2496 // Check the type of the expression.
2497 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2498 // It's a constant, evaluate reloc value.
2500 switch (getVariantKind(RelocStr)) {
2501 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2502 // Get the 1st 16-bits.
2503 Val = MCE->getValue() & 0xffff;
2505 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2506 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2507 // 16 bits being negative.
2508 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2510 case MCSymbolRefExpr::VK_Mips_HIGHER:
2511 // Get the 3rd 16-bits.
2512 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2514 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2515 // Get the 4th 16-bits.
2516 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2519 report_fatal_error("unsupported reloc value");
2521 return MCConstantExpr::Create(Val, getContext());
2524 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2525 // It's a symbol, create a symbolic expression from the symbol.
2526 StringRef Symbol = MSRE->getSymbol().getName();
2527 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2528 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2532 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2533 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2535 // Try to create target expression.
2536 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2537 return MipsMCExpr::Create(VK, Expr, getContext());
2539 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2540 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2541 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2545 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2546 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2547 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2550 // Just return the original expression.
2554 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2556 switch (Expr->getKind()) {
2557 case MCExpr::Constant:
2559 case MCExpr::SymbolRef:
2560 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2561 case MCExpr::Binary:
2562 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2563 if (!isEvaluated(BE->getLHS()))
2565 return isEvaluated(BE->getRHS());
2568 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2569 case MCExpr::Target:
2575 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2576 MCAsmParser &Parser = getParser();
2577 Parser.Lex(); // Eat the % token.
2578 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2579 if (Tok.isNot(AsmToken::Identifier))
2582 std::string Str = Tok.getIdentifier();
2584 Parser.Lex(); // Eat the identifier.
2585 // Now make an expression from the rest of the operand.
2586 const MCExpr *IdVal;
2589 if (getLexer().getKind() == AsmToken::LParen) {
2591 Parser.Lex(); // Eat the '(' token.
2592 if (getLexer().getKind() == AsmToken::Percent) {
2593 Parser.Lex(); // Eat the % token.
2594 const AsmToken &nextTok = Parser.getTok();
2595 if (nextTok.isNot(AsmToken::Identifier))
2598 Str += nextTok.getIdentifier();
2599 Parser.Lex(); // Eat the identifier.
2600 if (getLexer().getKind() != AsmToken::LParen)
2605 if (getParser().parseParenExpression(IdVal, EndLoc))
2608 while (getLexer().getKind() == AsmToken::RParen)
2609 Parser.Lex(); // Eat the ')' token.
2612 return true; // Parenthesis must follow the relocation operand.
2614 Res = evaluateRelocExpr(IdVal, Str);
2618 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2620 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2621 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2622 if (ResTy == MatchOperand_Success) {
2623 assert(Operands.size() == 1);
2624 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2625 StartLoc = Operand.getStartLoc();
2626 EndLoc = Operand.getEndLoc();
2628 // AFAIK, we only support numeric registers and named GPR's in CFI
2630 // Don't worry about eating tokens before failing. Using an unrecognised
2631 // register is a parse error.
2632 if (Operand.isGPRAsmReg()) {
2633 // Resolve to GPR32 or GPR64 appropriately.
2634 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2637 return (RegNo == (unsigned)-1);
2640 assert(Operands.size() == 0);
2641 return (RegNo == (unsigned)-1);
2644 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2645 MCAsmParser &Parser = getParser();
2649 while (getLexer().getKind() == AsmToken::LParen)
2652 switch (getLexer().getKind()) {
2655 case AsmToken::Identifier:
2656 case AsmToken::LParen:
2657 case AsmToken::Integer:
2658 case AsmToken::Minus:
2659 case AsmToken::Plus:
2661 Result = getParser().parseParenExpression(Res, S);
2663 Result = (getParser().parseExpression(Res));
2664 while (getLexer().getKind() == AsmToken::RParen)
2667 case AsmToken::Percent:
2668 Result = parseRelocOperand(Res);
2673 MipsAsmParser::OperandMatchResultTy
2674 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2675 MCAsmParser &Parser = getParser();
2676 DEBUG(dbgs() << "parseMemOperand\n");
2677 const MCExpr *IdVal = nullptr;
2679 bool isParenExpr = false;
2680 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2681 // First operand is the offset.
2682 S = Parser.getTok().getLoc();
2684 if (getLexer().getKind() == AsmToken::LParen) {
2689 if (getLexer().getKind() != AsmToken::Dollar) {
2690 if (parseMemOffset(IdVal, isParenExpr))
2691 return MatchOperand_ParseFail;
2693 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2694 if (Tok.isNot(AsmToken::LParen)) {
2695 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2696 if (Mnemonic.getToken() == "la") {
2698 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2699 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2700 return MatchOperand_Success;
2702 if (Tok.is(AsmToken::EndOfStatement)) {
2704 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2706 // Zero register assumed, add a memory operand with ZERO as its base.
2707 // "Base" will be managed by k_Memory.
2708 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2711 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2712 return MatchOperand_Success;
2714 Error(Parser.getTok().getLoc(), "'(' expected");
2715 return MatchOperand_ParseFail;
2718 Parser.Lex(); // Eat the '(' token.
2721 Res = parseAnyRegister(Operands);
2722 if (Res != MatchOperand_Success)
2725 if (Parser.getTok().isNot(AsmToken::RParen)) {
2726 Error(Parser.getTok().getLoc(), "')' expected");
2727 return MatchOperand_ParseFail;
2730 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2732 Parser.Lex(); // Eat the ')' token.
2735 IdVal = MCConstantExpr::Create(0, getContext());
2737 // Replace the register operand with the memory operand.
2738 std::unique_ptr<MipsOperand> op(
2739 static_cast<MipsOperand *>(Operands.back().release()));
2740 // Remove the register from the operands.
2741 // "op" will be managed by k_Memory.
2742 Operands.pop_back();
2743 // Add the memory operand.
2744 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2746 if (IdVal->EvaluateAsAbsolute(Imm))
2747 IdVal = MCConstantExpr::Create(Imm, getContext());
2748 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2749 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2753 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2754 return MatchOperand_Success;
2757 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2758 MCAsmParser &Parser = getParser();
2759 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2761 SMLoc S = Parser.getTok().getLoc();
2763 if (Sym->isVariable())
2764 Expr = Sym->getVariableValue();
2767 if (Expr->getKind() == MCExpr::SymbolRef) {
2768 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2769 StringRef DefSymbol = Ref->getSymbol().getName();
2770 if (DefSymbol.startswith("$")) {
2771 OperandMatchResultTy ResTy =
2772 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2773 if (ResTy == MatchOperand_Success) {
2776 } else if (ResTy == MatchOperand_ParseFail)
2777 llvm_unreachable("Should never ParseFail");
2780 } else if (Expr->getKind() == MCExpr::Constant) {
2782 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2784 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2791 MipsAsmParser::OperandMatchResultTy
2792 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2793 StringRef Identifier,
2795 int Index = matchCPURegisterName(Identifier);
2797 Operands.push_back(MipsOperand::createGPRReg(
2798 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2799 return MatchOperand_Success;
2802 Index = matchHWRegsRegisterName(Identifier);
2804 Operands.push_back(MipsOperand::createHWRegsReg(
2805 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2806 return MatchOperand_Success;
2809 Index = matchFPURegisterName(Identifier);
2811 Operands.push_back(MipsOperand::createFGRReg(
2812 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2813 return MatchOperand_Success;
2816 Index = matchFCCRegisterName(Identifier);
2818 Operands.push_back(MipsOperand::createFCCReg(
2819 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2820 return MatchOperand_Success;
2823 Index = matchACRegisterName(Identifier);
2825 Operands.push_back(MipsOperand::createACCReg(
2826 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2827 return MatchOperand_Success;
2830 Index = matchMSA128RegisterName(Identifier);
2832 Operands.push_back(MipsOperand::createMSA128Reg(
2833 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2834 return MatchOperand_Success;
2837 Index = matchMSA128CtrlRegisterName(Identifier);
2839 Operands.push_back(MipsOperand::createMSACtrlReg(
2840 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2841 return MatchOperand_Success;
2844 return MatchOperand_NoMatch;
2847 MipsAsmParser::OperandMatchResultTy
2848 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2849 MCAsmParser &Parser = getParser();
2850 auto Token = Parser.getLexer().peekTok(false);
2852 if (Token.is(AsmToken::Identifier)) {
2853 DEBUG(dbgs() << ".. identifier\n");
2854 StringRef Identifier = Token.getIdentifier();
2855 OperandMatchResultTy ResTy =
2856 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2858 } else if (Token.is(AsmToken::Integer)) {
2859 DEBUG(dbgs() << ".. integer\n");
2860 Operands.push_back(MipsOperand::createNumericReg(
2861 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2863 return MatchOperand_Success;
2866 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2868 return MatchOperand_NoMatch;
2871 MipsAsmParser::OperandMatchResultTy
2872 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2873 MCAsmParser &Parser = getParser();
2874 DEBUG(dbgs() << "parseAnyRegister\n");
2876 auto Token = Parser.getTok();
2878 SMLoc S = Token.getLoc();
2880 if (Token.isNot(AsmToken::Dollar)) {
2881 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2882 if (Token.is(AsmToken::Identifier)) {
2883 if (searchSymbolAlias(Operands))
2884 return MatchOperand_Success;
2886 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2887 return MatchOperand_NoMatch;
2889 DEBUG(dbgs() << ".. $\n");
2891 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2892 if (ResTy == MatchOperand_Success) {
2894 Parser.Lex(); // identifier
2899 MipsAsmParser::OperandMatchResultTy
2900 MipsAsmParser::parseImm(OperandVector &Operands) {
2901 MCAsmParser &Parser = getParser();
2902 switch (getLexer().getKind()) {
2904 return MatchOperand_NoMatch;
2905 case AsmToken::LParen:
2906 case AsmToken::Minus:
2907 case AsmToken::Plus:
2908 case AsmToken::Integer:
2909 case AsmToken::Tilde:
2910 case AsmToken::String:
2914 const MCExpr *IdVal;
2915 SMLoc S = Parser.getTok().getLoc();
2916 if (getParser().parseExpression(IdVal))
2917 return MatchOperand_ParseFail;
2919 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2920 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2921 return MatchOperand_Success;
2924 MipsAsmParser::OperandMatchResultTy
2925 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2926 MCAsmParser &Parser = getParser();
2927 DEBUG(dbgs() << "parseJumpTarget\n");
2929 SMLoc S = getLexer().getLoc();
2931 // Integers and expressions are acceptable
2932 OperandMatchResultTy ResTy = parseImm(Operands);
2933 if (ResTy != MatchOperand_NoMatch)
2936 // Registers are a valid target and have priority over symbols.
2937 ResTy = parseAnyRegister(Operands);
2938 if (ResTy != MatchOperand_NoMatch)
2941 const MCExpr *Expr = nullptr;
2942 if (Parser.parseExpression(Expr)) {
2943 // We have no way of knowing if a symbol was consumed so we must ParseFail
2944 return MatchOperand_ParseFail;
2947 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2948 return MatchOperand_Success;
2951 MipsAsmParser::OperandMatchResultTy
2952 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2953 MCAsmParser &Parser = getParser();
2954 const MCExpr *IdVal;
2955 // If the first token is '$' we may have register operand.
2956 if (Parser.getTok().is(AsmToken::Dollar))
2957 return MatchOperand_NoMatch;
2958 SMLoc S = Parser.getTok().getLoc();
2959 if (getParser().parseExpression(IdVal))
2960 return MatchOperand_ParseFail;
2961 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2962 assert(MCE && "Unexpected MCExpr type.");
2963 int64_t Val = MCE->getValue();
2964 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2965 Operands.push_back(MipsOperand::CreateImm(
2966 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2967 return MatchOperand_Success;
2970 MipsAsmParser::OperandMatchResultTy
2971 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2972 MCAsmParser &Parser = getParser();
2973 switch (getLexer().getKind()) {
2975 return MatchOperand_NoMatch;
2976 case AsmToken::LParen:
2977 case AsmToken::Plus:
2978 case AsmToken::Minus:
2979 case AsmToken::Integer:
2984 SMLoc S = Parser.getTok().getLoc();
2986 if (getParser().parseExpression(Expr))
2987 return MatchOperand_ParseFail;
2990 if (!Expr->EvaluateAsAbsolute(Val)) {
2991 Error(S, "expected immediate value");
2992 return MatchOperand_ParseFail;
2995 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2996 // and because the CPU always adds one to the immediate field, the allowed
2997 // range becomes 1..4. We'll only check the range here and will deal
2998 // with the addition/subtraction when actually decoding/encoding
3000 if (Val < 1 || Val > 4) {
3001 Error(S, "immediate not in range (1..4)");
3002 return MatchOperand_ParseFail;
3006 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3007 return MatchOperand_Success;
3010 MipsAsmParser::OperandMatchResultTy
3011 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3012 MCAsmParser &Parser = getParser();
3013 SmallVector<unsigned, 10> Regs;
3015 unsigned PrevReg = Mips::NoRegister;
3016 bool RegRange = false;
3017 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3019 if (Parser.getTok().isNot(AsmToken::Dollar))
3020 return MatchOperand_ParseFail;
3022 SMLoc S = Parser.getTok().getLoc();
3023 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3024 SMLoc E = getLexer().getLoc();
3025 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3026 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3028 // Remove last register operand because registers from register range
3029 // should be inserted first.
3030 if (RegNo == Mips::RA) {
3031 Regs.push_back(RegNo);
3033 unsigned TmpReg = PrevReg + 1;
3034 while (TmpReg <= RegNo) {
3035 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3036 Error(E, "invalid register operand");
3037 return MatchOperand_ParseFail;
3041 Regs.push_back(TmpReg++);
3047 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3048 (RegNo != Mips::RA)) {
3049 Error(E, "$16 or $31 expected");
3050 return MatchOperand_ParseFail;
3051 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3052 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3053 Error(E, "invalid register operand");
3054 return MatchOperand_ParseFail;
3055 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3056 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3057 Error(E, "consecutive register numbers expected");
3058 return MatchOperand_ParseFail;
3061 Regs.push_back(RegNo);
3064 if (Parser.getTok().is(AsmToken::Minus))
3067 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3068 !Parser.getTok().isNot(AsmToken::Comma)) {
3069 Error(E, "',' or '-' expected");
3070 return MatchOperand_ParseFail;
3073 Lex(); // Consume comma or minus
3074 if (Parser.getTok().isNot(AsmToken::Dollar))
3080 SMLoc E = Parser.getTok().getLoc();
3081 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3082 parseMemOperand(Operands);
3083 return MatchOperand_Success;
3086 MipsAsmParser::OperandMatchResultTy
3087 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3088 MCAsmParser &Parser = getParser();
3090 SMLoc S = Parser.getTok().getLoc();
3091 if (parseAnyRegister(Operands) != MatchOperand_Success)
3092 return MatchOperand_ParseFail;
3094 SMLoc E = Parser.getTok().getLoc();
3095 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3096 unsigned Reg = Op.getGPR32Reg();
3097 Operands.pop_back();
3098 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3099 return MatchOperand_Success;
3102 MipsAsmParser::OperandMatchResultTy
3103 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3104 MCAsmParser &Parser = getParser();
3105 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3106 SmallVector<unsigned, 10> Regs;
3108 if (Parser.getTok().isNot(AsmToken::Dollar))
3109 return MatchOperand_ParseFail;
3111 SMLoc S = Parser.getTok().getLoc();
3113 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3114 return MatchOperand_ParseFail;
3116 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3117 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3118 Regs.push_back(RegNo);
3120 SMLoc E = Parser.getTok().getLoc();
3121 if (Parser.getTok().isNot(AsmToken::Comma)) {
3122 Error(E, "',' expected");
3123 return MatchOperand_ParseFail;
3129 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3130 return MatchOperand_ParseFail;
3132 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3133 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3134 Regs.push_back(RegNo);
3136 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3138 return MatchOperand_Success;
3141 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3143 MCSymbolRefExpr::VariantKind VK =
3144 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3145 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3146 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3147 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3148 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3149 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3150 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3151 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3152 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3153 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3154 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3155 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3156 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3157 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3158 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3159 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3160 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3161 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3162 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3163 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3164 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3165 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3166 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3167 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3168 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3169 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3170 .Default(MCSymbolRefExpr::VK_None);
3172 assert(VK != MCSymbolRefExpr::VK_None);
3177 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3179 /// ::= '(', register, ')'
3180 /// handle it before we iterate so we don't get tripped up by the lack of
3182 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3183 MCAsmParser &Parser = getParser();
3184 if (getLexer().is(AsmToken::LParen)) {
3186 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3188 if (parseOperand(Operands, Name)) {
3189 SMLoc Loc = getLexer().getLoc();
3190 Parser.eatToEndOfStatement();
3191 return Error(Loc, "unexpected token in argument list");
3193 if (Parser.getTok().isNot(AsmToken::RParen)) {
3194 SMLoc Loc = getLexer().getLoc();
3195 Parser.eatToEndOfStatement();
3196 return Error(Loc, "unexpected token, expected ')'");
3199 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3205 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3206 /// either one of these.
3207 /// ::= '[', register, ']'
3208 /// ::= '[', integer, ']'
3209 /// handle it before we iterate so we don't get tripped up by the lack of
3211 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3212 OperandVector &Operands) {
3213 MCAsmParser &Parser = getParser();
3214 if (getLexer().is(AsmToken::LBrac)) {
3216 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3218 if (parseOperand(Operands, Name)) {
3219 SMLoc Loc = getLexer().getLoc();
3220 Parser.eatToEndOfStatement();
3221 return Error(Loc, "unexpected token in argument list");
3223 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3224 SMLoc Loc = getLexer().getLoc();
3225 Parser.eatToEndOfStatement();
3226 return Error(Loc, "unexpected token, expected ']'");
3229 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3235 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3236 SMLoc NameLoc, OperandVector &Operands) {
3237 MCAsmParser &Parser = getParser();
3238 DEBUG(dbgs() << "ParseInstruction\n");
3240 // We have reached first instruction, module directive are now forbidden.
3241 getTargetStreamer().forbidModuleDirective();
3243 // Check if we have valid mnemonic
3244 if (!mnemonicIsValid(Name, 0)) {
3245 Parser.eatToEndOfStatement();
3246 return Error(NameLoc, "unknown instruction");
3248 // First operand in MCInst is instruction mnemonic.
3249 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3251 // Read the remaining operands.
3252 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3253 // Read the first operand.
3254 if (parseOperand(Operands, Name)) {
3255 SMLoc Loc = getLexer().getLoc();
3256 Parser.eatToEndOfStatement();
3257 return Error(Loc, "unexpected token in argument list");
3259 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3261 // AFAIK, parenthesis suffixes are never on the first operand
3263 while (getLexer().is(AsmToken::Comma)) {
3264 Parser.Lex(); // Eat the comma.
3265 // Parse and remember the operand.
3266 if (parseOperand(Operands, Name)) {
3267 SMLoc Loc = getLexer().getLoc();
3268 Parser.eatToEndOfStatement();
3269 return Error(Loc, "unexpected token in argument list");
3271 // Parse bracket and parenthesis suffixes before we iterate
3272 if (getLexer().is(AsmToken::LBrac)) {
3273 if (parseBracketSuffix(Name, Operands))
3275 } else if (getLexer().is(AsmToken::LParen) &&
3276 parseParenSuffix(Name, Operands))
3280 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3281 SMLoc Loc = getLexer().getLoc();
3282 Parser.eatToEndOfStatement();
3283 return Error(Loc, "unexpected token in argument list");
3285 Parser.Lex(); // Consume the EndOfStatement.
3289 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3290 MCAsmParser &Parser = getParser();
3291 SMLoc Loc = getLexer().getLoc();
3292 Parser.eatToEndOfStatement();
3293 return Error(Loc, ErrorMsg);
3296 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3297 return Error(Loc, ErrorMsg);
3300 bool MipsAsmParser::parseSetNoAtDirective() {
3301 MCAsmParser &Parser = getParser();
3302 // Line should look like: ".set noat".
3304 // Set the $at register to $0.
3305 AssemblerOptions.back()->setATReg(0);
3307 Parser.Lex(); // Eat "noat".
3309 // If this is not the end of the statement, report an error.
3310 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3311 reportParseError("unexpected token, expected end of statement");
3315 getTargetStreamer().emitDirectiveSetNoAt();
3316 Parser.Lex(); // Consume the EndOfStatement.
3320 bool MipsAsmParser::parseSetAtDirective() {
3321 // Line can be: ".set at", which sets $at to $1
3322 // or ".set at=$reg", which sets $at to $reg.
3323 MCAsmParser &Parser = getParser();
3324 Parser.Lex(); // Eat "at".
3326 if (getLexer().is(AsmToken::EndOfStatement)) {
3327 // No register was specified, so we set $at to $1.
3328 AssemblerOptions.back()->setATReg(1);
3330 getTargetStreamer().emitDirectiveSetAt();
3331 Parser.Lex(); // Consume the EndOfStatement.
3335 if (getLexer().isNot(AsmToken::Equal)) {
3336 reportParseError("unexpected token, expected equals sign");
3339 Parser.Lex(); // Eat "=".
3341 if (getLexer().isNot(AsmToken::Dollar)) {
3342 if (getLexer().is(AsmToken::EndOfStatement)) {
3343 reportParseError("no register specified");
3346 reportParseError("unexpected token, expected dollar sign '$'");
3350 Parser.Lex(); // Eat "$".
3352 // Find out what "reg" is.
3354 const AsmToken &Reg = Parser.getTok();
3355 if (Reg.is(AsmToken::Identifier)) {
3356 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3357 } else if (Reg.is(AsmToken::Integer)) {
3358 AtRegNo = Reg.getIntVal();
3360 reportParseError("unexpected token, expected identifier or integer");
3364 // Check if $reg is a valid register. If it is, set $at to $reg.
3365 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3366 reportParseError("invalid register");
3369 Parser.Lex(); // Eat "reg".
3371 // If this is not the end of the statement, report an error.
3372 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3373 reportParseError("unexpected token, expected end of statement");
3377 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3379 Parser.Lex(); // Consume the EndOfStatement.
3383 bool MipsAsmParser::parseSetReorderDirective() {
3384 MCAsmParser &Parser = getParser();
3386 // If this is not the end of the statement, report an error.
3387 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3388 reportParseError("unexpected token, expected end of statement");
3391 AssemblerOptions.back()->setReorder();
3392 getTargetStreamer().emitDirectiveSetReorder();
3393 Parser.Lex(); // Consume the EndOfStatement.
3397 bool MipsAsmParser::parseSetNoReorderDirective() {
3398 MCAsmParser &Parser = getParser();
3400 // If this is not the end of the statement, report an error.
3401 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3402 reportParseError("unexpected token, expected end of statement");
3405 AssemblerOptions.back()->setNoReorder();
3406 getTargetStreamer().emitDirectiveSetNoReorder();
3407 Parser.Lex(); // Consume the EndOfStatement.
3411 bool MipsAsmParser::parseSetMacroDirective() {
3412 MCAsmParser &Parser = getParser();
3414 // If this is not the end of the statement, report an error.
3415 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3416 reportParseError("unexpected token, expected end of statement");
3419 AssemblerOptions.back()->setMacro();
3420 Parser.Lex(); // Consume the EndOfStatement.
3424 bool MipsAsmParser::parseSetNoMacroDirective() {
3425 MCAsmParser &Parser = getParser();
3427 // If this is not the end of the statement, report an error.
3428 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3429 reportParseError("unexpected token, expected end of statement");
3432 if (AssemblerOptions.back()->isReorder()) {
3433 reportParseError("`noreorder' must be set before `nomacro'");
3436 AssemblerOptions.back()->setNoMacro();
3437 Parser.Lex(); // Consume the EndOfStatement.
3441 bool MipsAsmParser::parseSetMsaDirective() {
3442 MCAsmParser &Parser = getParser();
3445 // If this is not the end of the statement, report an error.
3446 if (getLexer().isNot(AsmToken::EndOfStatement))
3447 return reportParseError("unexpected token, expected end of statement");
3449 setFeatureBits(Mips::FeatureMSA, "msa");
3450 getTargetStreamer().emitDirectiveSetMsa();
3454 bool MipsAsmParser::parseSetNoMsaDirective() {
3455 MCAsmParser &Parser = getParser();
3458 // If this is not the end of the statement, report an error.
3459 if (getLexer().isNot(AsmToken::EndOfStatement))
3460 return reportParseError("unexpected token, expected end of statement");
3462 clearFeatureBits(Mips::FeatureMSA, "msa");
3463 getTargetStreamer().emitDirectiveSetNoMsa();
3467 bool MipsAsmParser::parseSetNoDspDirective() {
3468 MCAsmParser &Parser = getParser();
3469 Parser.Lex(); // Eat "nodsp".
3471 // If this is not the end of the statement, report an error.
3472 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3473 reportParseError("unexpected token, expected end of statement");
3477 clearFeatureBits(Mips::FeatureDSP, "dsp");
3478 getTargetStreamer().emitDirectiveSetNoDsp();
3482 bool MipsAsmParser::parseSetMips16Directive() {
3483 MCAsmParser &Parser = getParser();
3484 Parser.Lex(); // Eat "mips16".
3486 // If this is not the end of the statement, report an error.
3487 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3488 reportParseError("unexpected token, expected end of statement");
3492 setFeatureBits(Mips::FeatureMips16, "mips16");
3493 getTargetStreamer().emitDirectiveSetMips16();
3494 Parser.Lex(); // Consume the EndOfStatement.
3498 bool MipsAsmParser::parseSetNoMips16Directive() {
3499 MCAsmParser &Parser = getParser();
3500 Parser.Lex(); // Eat "nomips16".
3502 // If this is not the end of the statement, report an error.
3503 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3504 reportParseError("unexpected token, expected end of statement");
3508 clearFeatureBits(Mips::FeatureMips16, "mips16");
3509 getTargetStreamer().emitDirectiveSetNoMips16();
3510 Parser.Lex(); // Consume the EndOfStatement.
3514 bool MipsAsmParser::parseSetFpDirective() {
3515 MCAsmParser &Parser = getParser();
3516 MipsABIFlagsSection::FpABIKind FpAbiVal;
3517 // Line can be: .set fp=32
3520 Parser.Lex(); // Eat fp token
3521 AsmToken Tok = Parser.getTok();
3522 if (Tok.isNot(AsmToken::Equal)) {
3523 reportParseError("unexpected token, expected equals sign '='");
3526 Parser.Lex(); // Eat '=' token.
3527 Tok = Parser.getTok();
3529 if (!parseFpABIValue(FpAbiVal, ".set"))
3532 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3533 reportParseError("unexpected token, expected end of statement");
3536 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3537 Parser.Lex(); // Consume the EndOfStatement.
3541 bool MipsAsmParser::parseSetPopDirective() {
3542 MCAsmParser &Parser = getParser();
3543 SMLoc Loc = getLexer().getLoc();
3546 if (getLexer().isNot(AsmToken::EndOfStatement))
3547 return reportParseError("unexpected token, expected end of statement");
3549 // Always keep an element on the options "stack" to prevent the user
3550 // from changing the initial options. This is how we remember them.
3551 if (AssemblerOptions.size() == 2)
3552 return reportParseError(Loc, ".set pop with no .set push");
3554 AssemblerOptions.pop_back();
3555 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3557 getTargetStreamer().emitDirectiveSetPop();
3561 bool MipsAsmParser::parseSetPushDirective() {
3562 MCAsmParser &Parser = getParser();
3564 if (getLexer().isNot(AsmToken::EndOfStatement))
3565 return reportParseError("unexpected token, expected end of statement");
3567 // Create a copy of the current assembler options environment and push it.
3568 AssemblerOptions.push_back(
3569 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3571 getTargetStreamer().emitDirectiveSetPush();
3575 bool MipsAsmParser::parseSetAssignment() {
3577 const MCExpr *Value;
3578 MCAsmParser &Parser = getParser();
3580 if (Parser.parseIdentifier(Name))
3581 reportParseError("expected identifier after .set");
3583 if (getLexer().isNot(AsmToken::Comma))
3584 return reportParseError("unexpected token, expected comma");
3587 if (Parser.parseExpression(Value))
3588 return reportParseError("expected valid expression after comma");
3590 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3591 Sym->setVariableValue(Value);
3596 bool MipsAsmParser::parseSetMips0Directive() {
3597 MCAsmParser &Parser = getParser();
3599 if (getLexer().isNot(AsmToken::EndOfStatement))
3600 return reportParseError("unexpected token, expected end of statement");
3602 // Reset assembler options to their initial values.
3603 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3604 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3606 getTargetStreamer().emitDirectiveSetMips0();
3610 bool MipsAsmParser::parseSetArchDirective() {
3611 MCAsmParser &Parser = getParser();
3613 if (getLexer().isNot(AsmToken::Equal))
3614 return reportParseError("unexpected token, expected equals sign");
3618 if (Parser.parseIdentifier(Arch))
3619 return reportParseError("expected arch identifier");
3621 StringRef ArchFeatureName =
3622 StringSwitch<StringRef>(Arch)
3623 .Case("mips1", "mips1")
3624 .Case("mips2", "mips2")
3625 .Case("mips3", "mips3")
3626 .Case("mips4", "mips4")
3627 .Case("mips5", "mips5")
3628 .Case("mips32", "mips32")
3629 .Case("mips32r2", "mips32r2")
3630 .Case("mips32r3", "mips32r3")
3631 .Case("mips32r5", "mips32r5")
3632 .Case("mips32r6", "mips32r6")
3633 .Case("mips64", "mips64")
3634 .Case("mips64r2", "mips64r2")
3635 .Case("mips64r3", "mips64r3")
3636 .Case("mips64r5", "mips64r5")
3637 .Case("mips64r6", "mips64r6")
3638 .Case("cnmips", "cnmips")
3639 .Case("r4000", "mips3") // This is an implementation of Mips3.
3642 if (ArchFeatureName.empty())
3643 return reportParseError("unsupported architecture");
3645 selectArch(ArchFeatureName);
3646 getTargetStreamer().emitDirectiveSetArch(Arch);
3650 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3651 MCAsmParser &Parser = getParser();
3653 if (getLexer().isNot(AsmToken::EndOfStatement))
3654 return reportParseError("unexpected token, expected end of statement");
3658 llvm_unreachable("Unimplemented feature");
3659 case Mips::FeatureDSP:
3660 setFeatureBits(Mips::FeatureDSP, "dsp");
3661 getTargetStreamer().emitDirectiveSetDsp();
3663 case Mips::FeatureMicroMips:
3664 getTargetStreamer().emitDirectiveSetMicroMips();
3666 case Mips::FeatureMips1:
3667 selectArch("mips1");
3668 getTargetStreamer().emitDirectiveSetMips1();
3670 case Mips::FeatureMips2:
3671 selectArch("mips2");
3672 getTargetStreamer().emitDirectiveSetMips2();
3674 case Mips::FeatureMips3:
3675 selectArch("mips3");
3676 getTargetStreamer().emitDirectiveSetMips3();
3678 case Mips::FeatureMips4:
3679 selectArch("mips4");
3680 getTargetStreamer().emitDirectiveSetMips4();
3682 case Mips::FeatureMips5:
3683 selectArch("mips5");
3684 getTargetStreamer().emitDirectiveSetMips5();
3686 case Mips::FeatureMips32:
3687 selectArch("mips32");
3688 getTargetStreamer().emitDirectiveSetMips32();
3690 case Mips::FeatureMips32r2:
3691 selectArch("mips32r2");
3692 getTargetStreamer().emitDirectiveSetMips32R2();
3694 case Mips::FeatureMips32r3:
3695 selectArch("mips32r3");
3696 getTargetStreamer().emitDirectiveSetMips32R3();
3698 case Mips::FeatureMips32r5:
3699 selectArch("mips32r5");
3700 getTargetStreamer().emitDirectiveSetMips32R5();
3702 case Mips::FeatureMips32r6:
3703 selectArch("mips32r6");
3704 getTargetStreamer().emitDirectiveSetMips32R6();
3706 case Mips::FeatureMips64:
3707 selectArch("mips64");
3708 getTargetStreamer().emitDirectiveSetMips64();
3710 case Mips::FeatureMips64r2:
3711 selectArch("mips64r2");
3712 getTargetStreamer().emitDirectiveSetMips64R2();
3714 case Mips::FeatureMips64r3:
3715 selectArch("mips64r3");
3716 getTargetStreamer().emitDirectiveSetMips64R3();
3718 case Mips::FeatureMips64r5:
3719 selectArch("mips64r5");
3720 getTargetStreamer().emitDirectiveSetMips64R5();
3722 case Mips::FeatureMips64r6:
3723 selectArch("mips64r6");
3724 getTargetStreamer().emitDirectiveSetMips64R6();
3730 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3731 MCAsmParser &Parser = getParser();
3732 if (getLexer().isNot(AsmToken::Comma)) {
3733 SMLoc Loc = getLexer().getLoc();
3734 Parser.eatToEndOfStatement();
3735 return Error(Loc, ErrorStr);
3738 Parser.Lex(); // Eat the comma.
3742 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3743 if (AssemblerOptions.back()->isReorder())
3744 Warning(Loc, ".cpload should be inside a noreorder section");
3746 if (inMips16Mode()) {
3747 reportParseError(".cpload is not supported in Mips16 mode");
3751 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3752 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3753 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3754 reportParseError("expected register containing function address");
3758 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3759 if (!RegOpnd.isGPRAsmReg()) {
3760 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3764 // If this is not the end of the statement, report an error.
3765 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3766 reportParseError("unexpected token, expected end of statement");
3770 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3774 bool MipsAsmParser::parseDirectiveCPSetup() {
3775 MCAsmParser &Parser = getParser();
3778 bool SaveIsReg = true;
3780 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3781 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3782 if (ResTy == MatchOperand_NoMatch) {
3783 reportParseError("expected register containing function address");
3784 Parser.eatToEndOfStatement();
3788 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3789 if (!FuncRegOpnd.isGPRAsmReg()) {
3790 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3791 Parser.eatToEndOfStatement();
3795 FuncReg = FuncRegOpnd.getGPR32Reg();
3798 if (!eatComma("unexpected token, expected comma"))
3801 ResTy = parseAnyRegister(TmpReg);
3802 if (ResTy == MatchOperand_NoMatch) {
3803 const AsmToken &Tok = Parser.getTok();
3804 if (Tok.is(AsmToken::Integer)) {
3805 Save = Tok.getIntVal();
3809 reportParseError("expected save register or stack offset");
3810 Parser.eatToEndOfStatement();
3814 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3815 if (!SaveOpnd.isGPRAsmReg()) {
3816 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3817 Parser.eatToEndOfStatement();
3820 Save = SaveOpnd.getGPR32Reg();
3823 if (!eatComma("unexpected token, expected comma"))
3827 if (Parser.parseExpression(Expr)) {
3828 reportParseError("expected expression");
3832 if (Expr->getKind() != MCExpr::SymbolRef) {
3833 reportParseError("expected symbol");
3836 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3838 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3843 bool MipsAsmParser::parseDirectiveNaN() {
3844 MCAsmParser &Parser = getParser();
3845 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3846 const AsmToken &Tok = Parser.getTok();
3848 if (Tok.getString() == "2008") {
3850 getTargetStreamer().emitDirectiveNaN2008();
3852 } else if (Tok.getString() == "legacy") {
3854 getTargetStreamer().emitDirectiveNaNLegacy();
3858 // If we don't recognize the option passed to the .nan
3859 // directive (e.g. no option or unknown option), emit an error.
3860 reportParseError("invalid option in .nan directive");
3864 bool MipsAsmParser::parseDirectiveSet() {
3865 MCAsmParser &Parser = getParser();
3866 // Get the next token.
3867 const AsmToken &Tok = Parser.getTok();
3869 if (Tok.getString() == "noat") {
3870 return parseSetNoAtDirective();
3871 } else if (Tok.getString() == "at") {
3872 return parseSetAtDirective();
3873 } else if (Tok.getString() == "arch") {
3874 return parseSetArchDirective();
3875 } else if (Tok.getString() == "fp") {
3876 return parseSetFpDirective();
3877 } else if (Tok.getString() == "pop") {
3878 return parseSetPopDirective();
3879 } else if (Tok.getString() == "push") {
3880 return parseSetPushDirective();
3881 } else if (Tok.getString() == "reorder") {
3882 return parseSetReorderDirective();
3883 } else if (Tok.getString() == "noreorder") {
3884 return parseSetNoReorderDirective();
3885 } else if (Tok.getString() == "macro") {
3886 return parseSetMacroDirective();
3887 } else if (Tok.getString() == "nomacro") {
3888 return parseSetNoMacroDirective();
3889 } else if (Tok.getString() == "mips16") {
3890 return parseSetMips16Directive();
3891 } else if (Tok.getString() == "nomips16") {
3892 return parseSetNoMips16Directive();
3893 } else if (Tok.getString() == "nomicromips") {
3894 getTargetStreamer().emitDirectiveSetNoMicroMips();
3895 Parser.eatToEndOfStatement();
3897 } else if (Tok.getString() == "micromips") {
3898 return parseSetFeature(Mips::FeatureMicroMips);
3899 } else if (Tok.getString() == "mips0") {
3900 return parseSetMips0Directive();
3901 } else if (Tok.getString() == "mips1") {
3902 return parseSetFeature(Mips::FeatureMips1);
3903 } else if (Tok.getString() == "mips2") {
3904 return parseSetFeature(Mips::FeatureMips2);
3905 } else if (Tok.getString() == "mips3") {
3906 return parseSetFeature(Mips::FeatureMips3);
3907 } else if (Tok.getString() == "mips4") {
3908 return parseSetFeature(Mips::FeatureMips4);
3909 } else if (Tok.getString() == "mips5") {
3910 return parseSetFeature(Mips::FeatureMips5);
3911 } else if (Tok.getString() == "mips32") {
3912 return parseSetFeature(Mips::FeatureMips32);
3913 } else if (Tok.getString() == "mips32r2") {
3914 return parseSetFeature(Mips::FeatureMips32r2);
3915 } else if (Tok.getString() == "mips32r3") {
3916 return parseSetFeature(Mips::FeatureMips32r3);
3917 } else if (Tok.getString() == "mips32r5") {
3918 return parseSetFeature(Mips::FeatureMips32r5);
3919 } else if (Tok.getString() == "mips32r6") {
3920 return parseSetFeature(Mips::FeatureMips32r6);
3921 } else if (Tok.getString() == "mips64") {
3922 return parseSetFeature(Mips::FeatureMips64);
3923 } else if (Tok.getString() == "mips64r2") {
3924 return parseSetFeature(Mips::FeatureMips64r2);
3925 } else if (Tok.getString() == "mips64r3") {
3926 return parseSetFeature(Mips::FeatureMips64r3);
3927 } else if (Tok.getString() == "mips64r5") {
3928 return parseSetFeature(Mips::FeatureMips64r5);
3929 } else if (Tok.getString() == "mips64r6") {
3930 return parseSetFeature(Mips::FeatureMips64r6);
3931 } else if (Tok.getString() == "dsp") {
3932 return parseSetFeature(Mips::FeatureDSP);
3933 } else if (Tok.getString() == "nodsp") {
3934 return parseSetNoDspDirective();
3935 } else if (Tok.getString() == "msa") {
3936 return parseSetMsaDirective();
3937 } else if (Tok.getString() == "nomsa") {
3938 return parseSetNoMsaDirective();
3940 // It is just an identifier, look for an assignment.
3941 parseSetAssignment();
3948 /// parseDataDirective
3949 /// ::= .word [ expression (, expression)* ]
3950 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3951 MCAsmParser &Parser = getParser();
3952 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3954 const MCExpr *Value;
3955 if (getParser().parseExpression(Value))
3958 getParser().getStreamer().EmitValue(Value, Size);
3960 if (getLexer().is(AsmToken::EndOfStatement))
3963 if (getLexer().isNot(AsmToken::Comma))
3964 return Error(L, "unexpected token, expected comma");
3973 /// parseDirectiveGpWord
3974 /// ::= .gpword local_sym
3975 bool MipsAsmParser::parseDirectiveGpWord() {
3976 MCAsmParser &Parser = getParser();
3977 const MCExpr *Value;
3978 // EmitGPRel32Value requires an expression, so we are using base class
3979 // method to evaluate the expression.
3980 if (getParser().parseExpression(Value))
3982 getParser().getStreamer().EmitGPRel32Value(Value);
3984 if (getLexer().isNot(AsmToken::EndOfStatement))
3985 return Error(getLexer().getLoc(),
3986 "unexpected token, expected end of statement");
3987 Parser.Lex(); // Eat EndOfStatement token.
3991 /// parseDirectiveGpDWord
3992 /// ::= .gpdword local_sym
3993 bool MipsAsmParser::parseDirectiveGpDWord() {
3994 MCAsmParser &Parser = getParser();
3995 const MCExpr *Value;
3996 // EmitGPRel64Value requires an expression, so we are using base class
3997 // method to evaluate the expression.
3998 if (getParser().parseExpression(Value))
4000 getParser().getStreamer().EmitGPRel64Value(Value);
4002 if (getLexer().isNot(AsmToken::EndOfStatement))
4003 return Error(getLexer().getLoc(),
4004 "unexpected token, expected end of statement");
4005 Parser.Lex(); // Eat EndOfStatement token.
4009 bool MipsAsmParser::parseDirectiveOption() {
4010 MCAsmParser &Parser = getParser();
4011 // Get the option token.
4012 AsmToken Tok = Parser.getTok();
4013 // At the moment only identifiers are supported.
4014 if (Tok.isNot(AsmToken::Identifier)) {
4015 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4016 Parser.eatToEndOfStatement();
4020 StringRef Option = Tok.getIdentifier();
4022 if (Option == "pic0") {
4023 getTargetStreamer().emitDirectiveOptionPic0();
4025 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4026 Error(Parser.getTok().getLoc(),
4027 "unexpected token, expected end of statement");
4028 Parser.eatToEndOfStatement();
4033 if (Option == "pic2") {
4034 getTargetStreamer().emitDirectiveOptionPic2();
4036 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4037 Error(Parser.getTok().getLoc(),
4038 "unexpected token, expected end of statement");
4039 Parser.eatToEndOfStatement();
4045 Warning(Parser.getTok().getLoc(),
4046 "unknown option, expected 'pic0' or 'pic2'");
4047 Parser.eatToEndOfStatement();
4051 /// parseInsnDirective
4053 bool MipsAsmParser::parseInsnDirective() {
4054 // If this is not the end of the statement, report an error.
4055 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4056 reportParseError("unexpected token, expected end of statement");
4060 // The actual label marking happens in
4061 // MipsELFStreamer::createPendingLabelRelocs().
4062 getTargetStreamer().emitDirectiveInsn();
4064 getParser().Lex(); // Eat EndOfStatement token.
4068 /// parseDirectiveModule
4069 /// ::= .module oddspreg
4070 /// ::= .module nooddspreg
4071 /// ::= .module fp=value
4072 bool MipsAsmParser::parseDirectiveModule() {
4073 MCAsmParser &Parser = getParser();
4074 MCAsmLexer &Lexer = getLexer();
4075 SMLoc L = Lexer.getLoc();
4077 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4078 // TODO : get a better message.
4079 reportParseError(".module directive must appear before any code");
4084 if (Parser.parseIdentifier(Option)) {
4085 reportParseError("expected .module option identifier");
4089 if (Option == "oddspreg") {
4090 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4091 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4093 // If this is not the end of the statement, report an error.
4094 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4095 reportParseError("unexpected token, expected end of statement");
4099 return false; // parseDirectiveModule has finished successfully.
4100 } else if (Option == "nooddspreg") {
4102 Error(L, "'.module nooddspreg' requires the O32 ABI");
4106 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4107 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4109 // If this is not the end of the statement, report an error.
4110 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4111 reportParseError("unexpected token, expected end of statement");
4115 return false; // parseDirectiveModule has finished successfully.
4116 } else if (Option == "fp") {
4117 return parseDirectiveModuleFP();
4119 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4123 /// parseDirectiveModuleFP
4127 bool MipsAsmParser::parseDirectiveModuleFP() {
4128 MCAsmParser &Parser = getParser();
4129 MCAsmLexer &Lexer = getLexer();
4131 if (Lexer.isNot(AsmToken::Equal)) {
4132 reportParseError("unexpected token, expected equals sign '='");
4135 Parser.Lex(); // Eat '=' token.
4137 MipsABIFlagsSection::FpABIKind FpABI;
4138 if (!parseFpABIValue(FpABI, ".module"))
4141 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4142 reportParseError("unexpected token, expected end of statement");
4146 // Emit appropriate flags.
4147 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4148 Parser.Lex(); // Consume the EndOfStatement.
4152 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4153 StringRef Directive) {
4154 MCAsmParser &Parser = getParser();
4155 MCAsmLexer &Lexer = getLexer();
4157 if (Lexer.is(AsmToken::Identifier)) {
4158 StringRef Value = Parser.getTok().getString();
4161 if (Value != "xx") {
4162 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4167 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4171 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4175 if (Lexer.is(AsmToken::Integer)) {
4176 unsigned Value = Parser.getTok().getIntVal();
4179 if (Value != 32 && Value != 64) {
4180 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4186 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4190 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4192 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4200 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4201 MCAsmParser &Parser = getParser();
4202 StringRef IDVal = DirectiveID.getString();
4204 if (IDVal == ".cpload")
4205 return parseDirectiveCpLoad(DirectiveID.getLoc());
4206 if (IDVal == ".dword") {
4207 parseDataDirective(8, DirectiveID.getLoc());
4210 if (IDVal == ".ent") {
4211 StringRef SymbolName;
4213 if (Parser.parseIdentifier(SymbolName)) {
4214 reportParseError("expected identifier after .ent");
4218 // There's an undocumented extension that allows an integer to
4219 // follow the name of the procedure which AFAICS is ignored by GAS.
4220 // Example: .ent foo,2
4221 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4222 if (getLexer().isNot(AsmToken::Comma)) {
4223 // Even though we accept this undocumented extension for compatibility
4224 // reasons, the additional integer argument does not actually change
4225 // the behaviour of the '.ent' directive, so we would like to discourage
4226 // its use. We do this by not referring to the extended version in
4227 // error messages which are not directly related to its use.
4228 reportParseError("unexpected token, expected end of statement");
4231 Parser.Lex(); // Eat the comma.
4232 const MCExpr *DummyNumber;
4233 int64_t DummyNumberVal;
4234 // If the user was explicitly trying to use the extended version,
4235 // we still give helpful extension-related error messages.
4236 if (Parser.parseExpression(DummyNumber)) {
4237 reportParseError("expected number after comma");
4240 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4241 reportParseError("expected an absolute expression after comma");
4246 // If this is not the end of the statement, report an error.
4247 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4248 reportParseError("unexpected token, expected end of statement");
4252 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4254 getTargetStreamer().emitDirectiveEnt(*Sym);
4259 if (IDVal == ".end") {
4260 StringRef SymbolName;
4262 if (Parser.parseIdentifier(SymbolName)) {
4263 reportParseError("expected identifier after .end");
4267 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4268 reportParseError("unexpected token, expected end of statement");
4272 if (CurrentFn == nullptr) {
4273 reportParseError(".end used without .ent");
4277 if ((SymbolName != CurrentFn->getName())) {
4278 reportParseError(".end symbol does not match .ent symbol");
4282 getTargetStreamer().emitDirectiveEnd(SymbolName);
4283 CurrentFn = nullptr;
4287 if (IDVal == ".frame") {
4288 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4289 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4290 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4291 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4292 reportParseError("expected stack register");
4296 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4297 if (!StackRegOpnd.isGPRAsmReg()) {
4298 reportParseError(StackRegOpnd.getStartLoc(),
4299 "expected general purpose register");
4302 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4304 if (Parser.getTok().is(AsmToken::Comma))
4307 reportParseError("unexpected token, expected comma");
4311 // Parse the frame size.
4312 const MCExpr *FrameSize;
4313 int64_t FrameSizeVal;
4315 if (Parser.parseExpression(FrameSize)) {
4316 reportParseError("expected frame size value");
4320 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4321 reportParseError("frame size not an absolute expression");
4325 if (Parser.getTok().is(AsmToken::Comma))
4328 reportParseError("unexpected token, expected comma");
4332 // Parse the return register.
4334 ResTy = parseAnyRegister(TmpReg);
4335 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4336 reportParseError("expected return register");
4340 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4341 if (!ReturnRegOpnd.isGPRAsmReg()) {
4342 reportParseError(ReturnRegOpnd.getStartLoc(),
4343 "expected general purpose register");
4347 // If this is not the end of the statement, report an error.
4348 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4349 reportParseError("unexpected token, expected end of statement");
4353 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4354 ReturnRegOpnd.getGPR32Reg());
4358 if (IDVal == ".set") {
4359 return parseDirectiveSet();
4362 if (IDVal == ".mask" || IDVal == ".fmask") {
4363 // .mask bitmask, frame_offset
4364 // bitmask: One bit for each register used.
4365 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4366 // first register is expected to be saved.
4368 // .mask 0x80000000, -4
4369 // .fmask 0x80000000, -4
4372 // Parse the bitmask
4373 const MCExpr *BitMask;
4376 if (Parser.parseExpression(BitMask)) {
4377 reportParseError("expected bitmask value");
4381 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4382 reportParseError("bitmask not an absolute expression");
4386 if (Parser.getTok().is(AsmToken::Comma))
4389 reportParseError("unexpected token, expected comma");
4393 // Parse the frame_offset
4394 const MCExpr *FrameOffset;
4395 int64_t FrameOffsetVal;
4397 if (Parser.parseExpression(FrameOffset)) {
4398 reportParseError("expected frame offset value");
4402 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4403 reportParseError("frame offset not an absolute expression");
4407 // If this is not the end of the statement, report an error.
4408 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4409 reportParseError("unexpected token, expected end of statement");
4413 if (IDVal == ".mask")
4414 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4416 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4420 if (IDVal == ".nan")
4421 return parseDirectiveNaN();
4423 if (IDVal == ".gpword") {
4424 parseDirectiveGpWord();
4428 if (IDVal == ".gpdword") {
4429 parseDirectiveGpDWord();
4433 if (IDVal == ".word") {
4434 parseDataDirective(4, DirectiveID.getLoc());
4438 if (IDVal == ".option")
4439 return parseDirectiveOption();
4441 if (IDVal == ".abicalls") {
4442 getTargetStreamer().emitDirectiveAbiCalls();
4443 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4444 Error(Parser.getTok().getLoc(),
4445 "unexpected token, expected end of statement");
4447 Parser.eatToEndOfStatement();
4452 if (IDVal == ".cpsetup")
4453 return parseDirectiveCPSetup();
4455 if (IDVal == ".module")
4456 return parseDirectiveModule();
4458 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4459 return parseInternalDirectiveReallowModule();
4461 if (IDVal == ".insn")
4462 return parseInsnDirective();
4467 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4468 // If this is not the end of the statement, report an error.
4469 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4470 reportParseError("unexpected token, expected end of statement");
4474 getTargetStreamer().reallowModuleDirective();
4476 getParser().Lex(); // Eat EndOfStatement token.
4480 extern "C" void LLVMInitializeMipsAsmParser() {
4481 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4482 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4483 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4484 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4487 #define GET_REGISTER_MATCHER
4488 #define GET_MATCHER_IMPLEMENTATION
4489 #include "MipsGenAsmMatcher.inc"